New jit API entrypoint: gcc_jit_context_set_logfile
[official-gcc.git] / gcc / jit / jit-recording.c
bloba872063630acb1632607b141baab8109274b7cb3
1 /* Internals of libgccjit: classes for recording calls made to the JIT API.
2 Copyright (C) 2013-2015 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "opts.h"
26 #include "tree.h"
27 #include "pretty-print.h"
29 #include <pthread.h>
31 #include "jit-common.h"
32 #include "jit-builtins.h"
33 #include "jit-logging.h"
34 #include "jit-recording.h"
35 #include "jit-playback.h"
37 namespace gcc {
38 namespace jit {
40 // class dump
42 dump::dump (recording::context &ctxt,
43 const char *filename,
44 bool update_locations)
45 : m_ctxt (ctxt),
46 m_filename (filename),
47 m_update_locations (update_locations),
48 m_line (0),
49 m_column (0)
51 m_file = fopen (filename, "w");
52 if (!m_file)
53 ctxt.add_error (NULL,
54 "error opening dump file %s for writing: %s",
55 filename,
56 xstrerror (errno));
59 dump::~dump ()
61 if (m_file)
63 int err = fclose (m_file);
64 if (err)
65 m_ctxt.add_error (NULL,
66 "error closing dump file %s: %s",
67 m_filename,
68 xstrerror (errno));
72 /* Write the given message to the dump, using printf-formatting
73 conventions, updating the line/column within the dump.
75 Emit an error on the context if a failure occurs. */
77 void
78 dump::write (const char *fmt, ...)
80 va_list ap;
81 char *buf = NULL;
83 /* If there was an error opening the file, we've already reported it.
84 Don't attempt further work. */
85 if (!m_file)
86 return;
88 va_start (ap, fmt);
89 vasprintf (&buf, fmt, ap);
90 va_end (ap);
92 if (!buf)
94 m_ctxt.add_error (NULL, "malloc failure writing to dumpfile %s",
95 m_filename);
96 return;
99 if (fwrite (buf, strlen (buf), 1, m_file) != 1)
100 m_ctxt.add_error (NULL, "error writing to dump file %s",
101 m_filename);
103 /* Update line/column: */
104 for (const char *ptr = buf; *ptr; ptr++)
106 if ('\n' == *ptr)
108 m_line++;
109 m_column = 0;
111 else
112 m_column++;
115 free (buf);
118 /* Construct a gcc::jit::recording::location instance for the current
119 location within the dump. */
121 recording::location *
122 dump::make_location () const
124 return m_ctxt.new_location (m_filename, m_line, m_column);
127 /**********************************************************************
128 Recording.
129 **********************************************************************/
131 /* Get the playback::location for the given recording::location,
132 handling a NULL input with a NULL output. */
134 playback::location *
135 recording::playback_location (replayer *r, recording::location *loc)
137 if (loc)
138 return loc->playback_location (r);
139 else
140 return NULL;
143 /* Get a const char * for the given recording::string
144 handling a NULL input with a NULL output. */
146 const char *
147 recording::playback_string (recording::string *str)
149 if (str)
150 return str->c_str ();
151 else
152 return NULL;
155 /* Get the playback::block for the given recording::block,
156 handling a NULL input with a NULL output. */
158 playback::block *
159 recording::playback_block (recording::block *b)
161 if (b)
162 return b->playback_block ();
163 else
164 return NULL;
167 /* Methods of cc::jit::recording::context. */
169 /* The constructor for gcc::jit::recording::context, used by
170 gcc_jit_context_acquire and gcc_jit_context_new_child_context. */
172 recording::context::context (context *parent_ctxt)
173 : log_user (NULL),
174 m_parent_ctxt (parent_ctxt),
175 m_error_count (0),
176 m_first_error_str (NULL),
177 m_owns_first_error_str (false),
178 m_mementos (),
179 m_compound_types (),
180 m_functions (),
181 m_FILE_type (NULL),
182 m_builtins_manager(NULL)
184 if (parent_ctxt)
186 /* Inherit options from parent. */
187 for (unsigned i = 0;
188 i < sizeof (m_str_options) / sizeof (m_str_options[0]);
189 i++)
191 const char *parent_opt = parent_ctxt->m_str_options[i];
192 m_str_options[i] = parent_opt ? xstrdup (parent_opt) : NULL;
194 memcpy (m_int_options,
195 parent_ctxt->m_int_options,
196 sizeof (m_int_options));
197 memcpy (m_bool_options,
198 parent_ctxt->m_bool_options,
199 sizeof (m_bool_options));
200 set_logger (parent_ctxt->get_logger ());
202 else
204 memset (m_str_options, 0, sizeof (m_str_options));
205 memset (m_int_options, 0, sizeof (m_int_options));
206 memset (m_bool_options, 0, sizeof (m_bool_options));
209 memset (m_basic_types, 0, sizeof (m_basic_types));
212 /* The destructor for gcc::jit::recording::context, implicitly used by
213 gcc_jit_context_release. */
215 recording::context::~context ()
217 JIT_LOG_SCOPE (get_logger ());
218 int i;
219 memento *m;
220 FOR_EACH_VEC_ELT (m_mementos, i, m)
222 delete m;
225 for (i = 0; i < GCC_JIT_NUM_STR_OPTIONS; ++i)
226 free (m_str_options[i]);
228 if (m_builtins_manager)
229 delete m_builtins_manager;
231 if (m_owns_first_error_str)
232 free (m_first_error_str);
235 /* Add the given mememto to the list of those tracked by this
236 gcc::jit::recording::context, so that e.g. it can be deleted
237 when this context is released. */
239 void
240 recording::context::record (memento *m)
242 gcc_assert (m);
244 m_mementos.safe_push (m);
247 /* Replay this context (and any parents) into the given replayer. */
249 void
250 recording::context::replay_into (replayer *r)
252 JIT_LOG_SCOPE (get_logger ());
253 int i;
254 memento *m;
256 /* If we have a parent context, we must replay it. This will
257 recursively walk backwards up the historical tree, then replay things
258 forwards "in historical order", starting with the ultimate parent
259 context, until we reach the "this" context.
261 Note that we fully replay the parent, then fully replay the child,
262 which means that inter-context references can only exist from child
263 to parent, not the other way around.
265 All of this replaying is suboptimal - it would be better to do the
266 work for the parent context *once*, rather than replaying the parent
267 every time we replay each child. However, fixing this requires deep
268 surgery to lifetime-management: we'd need every context family tree
269 to have its own GC heap, and to initialize the GCC code to use that
270 heap (with a mutex on such a heap). */
271 if (m_parent_ctxt)
272 m_parent_ctxt->replay_into (r);
274 if (r->errors_occurred ())
275 return;
277 /* Replay this context's saved operations into r. */
278 FOR_EACH_VEC_ELT (m_mementos, i, m)
280 /* Disabled low-level debugging, here if we need it: print what
281 we're replaying.
282 Note that the calls to get_debug_string might lead to more
283 mementos being created for the strings.
284 This can also be used to exercise the debug_string
285 machinery. */
286 if (0)
287 printf ("context %p replaying (%p): %s\n",
288 (void *)this, (void *)m, m->get_debug_string ());
290 m->replay_into (r);
292 if (r->errors_occurred ())
293 return;
297 /* During a playback, we associate objects from the recording with
298 their counterparts during this playback.
300 For simplicity, we store this within the recording objects.
302 The following method cleans away these associations, to ensure that
303 we never have out-of-date associations lingering on subsequent
304 playbacks (the objects pointed to are GC-managed, but the
305 recording objects don't own refs to them). */
307 void
308 recording::context::disassociate_from_playback ()
310 JIT_LOG_SCOPE (get_logger ());
311 int i;
312 memento *m;
314 if (m_parent_ctxt)
315 m_parent_ctxt->disassociate_from_playback ();
317 FOR_EACH_VEC_ELT (m_mementos, i, m)
319 m->set_playback_obj (NULL);
323 /* Create a recording::string instance and add it to this context's list
324 of mementos.
326 This creates a fresh copy of the given 0-terminated buffer. */
328 recording::string *
329 recording::context::new_string (const char *text)
331 if (!text)
332 return NULL;
334 recording::string *result = new string (this, text);
335 record (result);
336 return result;
339 /* Create a recording::location instance and add it to this context's
340 list of mementos.
342 Implements the post-error-checking part of
343 gcc_jit_context_new_location. */
345 recording::location *
346 recording::context::new_location (const char *filename,
347 int line,
348 int column)
350 recording::location *result =
351 new recording::location (this,
352 new_string (filename),
353 line, column);
354 record (result);
355 return result;
358 /* If we haven't seen this enum value yet, create a recording::type
359 instance and add it to this context's list of mementos.
361 If we have seen it before, reuse our cached value, so that repeated
362 calls on the context give the same object.
364 If we have a parent context, the cache is within the ultimate
365 ancestor context.
367 Implements the post-error-checking part of
368 gcc_jit_context_get_type. */
370 recording::type *
371 recording::context::get_type (enum gcc_jit_types kind)
373 if (!m_basic_types[kind])
375 if (m_parent_ctxt)
376 m_basic_types[kind] = m_parent_ctxt->get_type (kind);
377 else
379 recording::type *result = new memento_of_get_type (this, kind);
380 record (result);
381 m_basic_types[kind] = result;
385 return m_basic_types[kind];
388 /* Get a recording::type instance for the given size and signedness.
389 This is implemented in terms of recording::context::get_type
390 above.
392 Implements the post-error-checking part of
393 gcc_jit_context_get_int_type. */
395 recording::type *
396 recording::context::get_int_type (int num_bytes, int is_signed)
398 /* We can't use a switch here since some of the values are macros affected
399 by options; e.g. i386.h has
400 #define LONG_TYPE_SIZE (TARGET_X32 ? 32 : BITS_PER_WORD)
401 Compare with tree.c's make_or_reuse_type. Note that the _SIZE macros
402 are in bits, rather than bytes.
404 const int num_bits = num_bytes * 8;
405 if (num_bits == INT_TYPE_SIZE)
406 return get_type (is_signed
407 ? GCC_JIT_TYPE_INT
408 : GCC_JIT_TYPE_UNSIGNED_INT);
409 if (num_bits == CHAR_TYPE_SIZE)
410 return get_type (is_signed
411 ? GCC_JIT_TYPE_SIGNED_CHAR
412 : GCC_JIT_TYPE_UNSIGNED_CHAR);
413 if (num_bits == SHORT_TYPE_SIZE)
414 return get_type (is_signed
415 ? GCC_JIT_TYPE_SHORT
416 : GCC_JIT_TYPE_UNSIGNED_SHORT);
417 if (num_bits == LONG_TYPE_SIZE)
418 return get_type (is_signed
419 ? GCC_JIT_TYPE_LONG
420 : GCC_JIT_TYPE_UNSIGNED_LONG);
421 if (num_bits == LONG_LONG_TYPE_SIZE)
422 return get_type (is_signed
423 ? GCC_JIT_TYPE_LONG_LONG
424 : GCC_JIT_TYPE_UNSIGNED_LONG_LONG);
426 /* Some other size, not corresponding to the C int types. */
427 /* To be written: support arbitrary other sizes, sharing by
428 memoizing at the recording::context level? */
429 gcc_unreachable ();
432 /* Create a recording::type instance and add it to this context's list
433 of mementos.
435 Implements the post-error-checking part of
436 gcc_jit_context_new_array_type. */
438 recording::type *
439 recording::context::new_array_type (recording::location *loc,
440 recording::type *element_type,
441 int num_elements)
443 if (struct_ *s = element_type->dyn_cast_struct ())
444 if (!s->get_fields ())
446 add_error (NULL,
447 "cannot create an array of type %s"
448 " until the fields have been set",
449 s->get_name ()->c_str ());
450 return NULL;
452 recording::type *result =
453 new recording::array_type (this, loc, element_type, num_elements);
454 record (result);
455 return result;
458 /* Create a recording::field instance and add it to this context's list
459 of mementos.
461 Implements the post-error-checking part of
462 gcc_jit_context_new_field. */
464 recording::field *
465 recording::context::new_field (recording::location *loc,
466 recording::type *type,
467 const char *name)
469 recording::field *result =
470 new recording::field (this, loc, type, new_string (name));
471 record (result);
472 return result;
475 /* Create a recording::struct_ instance and add it to this context's
476 list of mementos and list of compound types.
478 Implements the post-error-checking part of
479 gcc_jit_context_new_struct_type. */
481 recording::struct_ *
482 recording::context::new_struct_type (recording::location *loc,
483 const char *name)
485 recording::struct_ *result = new struct_ (this, loc, new_string (name));
486 record (result);
487 m_compound_types.safe_push (result);
488 return result;
491 /* Create a recording::union_ instance and add it to this context's
492 list of mementos and list of compound types.
494 Implements the first post-error-checking part of
495 gcc_jit_context_new_union_type. */
497 recording::union_ *
498 recording::context::new_union_type (recording::location *loc,
499 const char *name)
501 recording::union_ *result = new union_ (this, loc, new_string (name));
502 record (result);
503 m_compound_types.safe_push (result);
504 return result;
507 /* Create a recording::function_type instance and add it to this context's
508 list of mementos.
510 Used by new_function_ptr_type and by builtins_manager::make_fn_type. */
512 recording::function_type *
513 recording::context::new_function_type (recording::type *return_type,
514 int num_params,
515 recording::type **param_types,
516 int is_variadic)
518 recording::function_type *fn_type
519 = new function_type (this,
520 return_type,
521 num_params,
522 param_types,
523 is_variadic);
524 record (fn_type);
525 return fn_type;
528 /* Create a recording::type instance and add it to this context's list
529 of mementos.
531 Implements the post-error-checking part of
532 gcc_jit_context_new_function_ptr_type. */
534 recording::type *
535 recording::context::new_function_ptr_type (recording::location *, /* unused loc */
536 recording::type *return_type,
537 int num_params,
538 recording::type **param_types,
539 int is_variadic)
541 recording::function_type *fn_type
542 = new_function_type (return_type,
543 num_params,
544 param_types,
545 is_variadic);
547 /* Return a pointer-type to the the function type. */
548 return fn_type->get_pointer ();
551 /* Create a recording::param instance and add it to this context's list
552 of mementos.
554 Implements the post-error-checking part of
555 gcc_jit_context_new_param. */
557 recording::param *
558 recording::context::new_param (recording::location *loc,
559 recording::type *type,
560 const char *name)
562 recording::param *result = new recording::param (this, loc, type, new_string (name));
563 record (result);
564 return result;
567 /* Create a recording::function instance and add it to this context's list
568 of mementos and list of functions.
570 Implements the post-error-checking part of
571 gcc_jit_context_new_function. */
573 recording::function *
574 recording::context::new_function (recording::location *loc,
575 enum gcc_jit_function_kind kind,
576 recording::type *return_type,
577 const char *name,
578 int num_params,
579 recording::param **params,
580 int is_variadic,
581 enum built_in_function builtin_id)
583 recording::function *result =
584 new recording::function (this,
585 loc, kind, return_type,
586 new_string (name),
587 num_params, params, is_variadic,
588 builtin_id);
589 record (result);
590 m_functions.safe_push (result);
592 return result;
595 /* Locate the builtins_manager (if any) for this family of contexts,
596 creating it if it doesn't exist already.
598 All of the recording contexts in a family share one builtins_manager:
599 if we have a child context, follow the parent links to get the
600 ultimate ancestor context, and look for it/store it there. */
602 builtins_manager *
603 recording::context::get_builtins_manager ()
605 if (m_parent_ctxt)
606 return m_parent_ctxt->get_builtins_manager ();
608 if (!m_builtins_manager)
609 m_builtins_manager = new builtins_manager (this);
611 return m_builtins_manager;
614 /* Get a recording::function instance, which is lazily-created and added
615 to the context's lists of mementos.
617 Implements the post-error-checking part of
618 gcc_jit_context_get_builtin_function. */
620 recording::function *
621 recording::context::get_builtin_function (const char *name)
623 builtins_manager *bm = get_builtins_manager ();
624 return bm->get_builtin_function (name);
627 /* Create a recording::global instance and add it to this context's list
628 of mementos.
630 Implements the post-error-checking part of
631 gcc_jit_context_new_global. */
633 recording::lvalue *
634 recording::context::new_global (recording::location *loc,
635 recording::type *type,
636 const char *name)
638 recording::lvalue *result =
639 new recording::global (this, loc, type, new_string (name));
640 record (result);
641 return result;
644 /* Create a recording::memento_of_new_rvalue_from_int instance and add
645 it to this context's list of mementos.
647 Implements the post-error-checking part of
648 gcc_jit_context_new_rvalue_from_int. */
650 recording::rvalue *
651 recording::context::new_rvalue_from_int (recording::type *type,
652 int value)
654 recording::rvalue *result =
655 new memento_of_new_rvalue_from_int (this, NULL, type, value);
656 record (result);
657 return result;
660 /* Create a recording::memento_of_new_rvalue_from_double instance and
661 add it to this context's list of mementos.
663 Implements the post-error-checking part of
664 gcc_jit_context_new_rvalue_from_double. */
666 recording::rvalue *
667 recording::context::new_rvalue_from_double (recording::type *type,
668 double value)
670 recording::rvalue *result =
671 new memento_of_new_rvalue_from_double (this, NULL, type, value);
672 record (result);
673 return result;
676 /* Create a recording::memento_of_new_rvalue_from_ptr instance and add
677 it to this context's list of mementos.
679 Implements the post-error-checking part of
680 gcc_jit_context_new_rvalue_from_ptr. */
682 recording::rvalue *
683 recording::context::new_rvalue_from_ptr (recording::type *type,
684 void *value)
686 recording::rvalue *result =
687 new memento_of_new_rvalue_from_ptr (this, NULL, type, value);
688 record (result);
689 return result;
692 /* Create a recording::memento_of_new_string_literal instance and add it
693 to this context's list of mementos.
695 Implements the post-error-checking part of
696 gcc_jit_context_new_string_literal. */
698 recording::rvalue *
699 recording::context::new_string_literal (const char *value)
701 recording::rvalue *result =
702 new memento_of_new_string_literal (this, NULL, new_string (value));
703 record (result);
704 return result;
707 /* Create a recording::unary_op instance and add it to this context's
708 list of mementos.
710 Implements the post-error-checking part of
711 gcc_jit_context_new_unary_op. */
713 recording::rvalue *
714 recording::context::new_unary_op (recording::location *loc,
715 enum gcc_jit_unary_op op,
716 recording::type *result_type,
717 recording::rvalue *a)
719 recording::rvalue *result =
720 new unary_op (this, loc, op, result_type, a);
721 record (result);
722 return result;
725 /* Create a recording::binary_op instance and add it to this context's
726 list of mementos.
728 Implements the post-error-checking part of
729 gcc_jit_context_new_binary_op. */
731 recording::rvalue *
732 recording::context::new_binary_op (recording::location *loc,
733 enum gcc_jit_binary_op op,
734 recording::type *result_type,
735 recording::rvalue *a,
736 recording::rvalue *b)
738 recording::rvalue *result =
739 new binary_op (this, loc, op, result_type, a, b);
740 record (result);
741 return result;
744 /* Create a recording::comparison instance and add it to this context's
745 list of mementos.
747 Implements the post-error-checking part of
748 gcc_jit_context_new_comparison. */
750 recording::rvalue *
751 recording::context::new_comparison (recording::location *loc,
752 enum gcc_jit_comparison op,
753 recording::rvalue *a,
754 recording::rvalue *b)
756 recording::rvalue *result = new comparison (this, loc, op, a, b);
757 record (result);
758 return result;
761 /* Create a recording::cast instance and add it to this context's list
762 of mementos.
764 Implements the post-error-checking part of
765 gcc_jit_context_new_cast. */
767 recording::rvalue *
768 recording::context::new_cast (recording::location *loc,
769 recording::rvalue *expr,
770 recording::type *type_)
772 recording::rvalue *result = new cast (this, loc, expr, type_);
773 record (result);
774 return result;
777 /* Create a recording::call instance and add it to this context's list
778 of mementos.
780 Implements the post-error-checking part of
781 gcc_jit_context_new_call. */
783 recording::rvalue *
784 recording::context::new_call (recording::location *loc,
785 function *func,
786 int numargs , recording::rvalue **args)
788 recording::rvalue *result = new call (this, loc, func, numargs, args);
789 record (result);
790 return result;
793 /* Create a recording::call_through_ptr instance and add it to this
794 context's list of mementos.
796 Implements the post-error-checking part of
797 gcc_jit_context_new_call_through_ptr. */
799 recording::rvalue *
800 recording::context::new_call_through_ptr (recording::location *loc,
801 recording::rvalue *fn_ptr,
802 int numargs,
803 recording::rvalue **args)
805 recording::rvalue *result = new call_through_ptr (this, loc, fn_ptr, numargs, args);
806 record (result);
807 return result;
810 /* Create a recording::array_access instance and add it to this context's list
811 of mementos.
813 Implements the post-error-checking part of
814 gcc_jit_context_new_array_access. */
816 recording::lvalue *
817 recording::context::new_array_access (recording::location *loc,
818 recording::rvalue *ptr,
819 recording::rvalue *index)
821 recording::lvalue *result = new array_access (this, loc, ptr, index);
822 record (result);
823 return result;
826 /* Set the given string option for this context, or add an error if
827 it's not recognized.
829 Implements the post-error-checking part of
830 gcc_jit_context_set_str_option. */
832 void
833 recording::context::set_str_option (enum gcc_jit_str_option opt,
834 const char *value)
836 if (opt < 0 || opt >= GCC_JIT_NUM_STR_OPTIONS)
838 add_error (NULL,
839 "unrecognized (enum gcc_jit_str_option) value: %i", opt);
840 return;
842 free (m_str_options[opt]);
843 m_str_options[opt] = value ? xstrdup (value) : NULL;
846 /* Set the given integer option for this context, or add an error if
847 it's not recognized.
849 Implements the post-error-checking part of
850 gcc_jit_context_set_int_option. */
852 void
853 recording::context::set_int_option (enum gcc_jit_int_option opt,
854 int value)
856 if (opt < 0 || opt >= GCC_JIT_NUM_INT_OPTIONS)
858 add_error (NULL,
859 "unrecognized (enum gcc_jit_int_option) value: %i", opt);
860 return;
862 m_int_options[opt] = value;
865 /* Set the given boolean option for this context, or add an error if
866 it's not recognized.
868 Implements the post-error-checking part of
869 gcc_jit_context_set_bool_option. */
871 void
872 recording::context::set_bool_option (enum gcc_jit_bool_option opt,
873 int value)
875 if (opt < 0 || opt >= GCC_JIT_NUM_BOOL_OPTIONS)
877 add_error (NULL,
878 "unrecognized (enum gcc_jit_bool_option) value: %i", opt);
879 return;
881 m_bool_options[opt] = value ? true : false;
884 /* Add the given dumpname/out_ptr pair to this context's list of requested
885 dumps.
887 Implements the post-error-checking part of
888 gcc_jit_context_enable_dump. */
890 void
891 recording::context::enable_dump (const char *dumpname,
892 char **out_ptr)
894 requested_dump d;
895 gcc_assert (dumpname);
896 gcc_assert (out_ptr);
898 d.m_dumpname = dumpname;
899 d.m_out_ptr = out_ptr;
900 *out_ptr = NULL;
901 m_requested_dumps.safe_push (d);
904 /* Validate this context, and if it passes, compile it within a
905 mutex.
907 Implements the post-error-checking part of
908 gcc_jit_context_compile. */
910 result *
911 recording::context::compile ()
913 JIT_LOG_SCOPE (get_logger ());
915 validate ();
917 if (errors_occurred ())
918 return NULL;
920 /* Set up a playback context. */
921 ::gcc::jit::playback::context replayer (this);
923 /* Use it. */
924 result *result_obj = replayer.compile ();
926 return result_obj;
929 /* Format the given error using printf's conventions, print
930 it to stderr, and add it to the context. */
932 void
933 recording::context::add_error (location *loc, const char *fmt, ...)
935 va_list ap;
936 va_start (ap, fmt);
937 add_error_va (loc, fmt, ap);
938 va_end (ap);
941 /* Format the given error using printf's conventions, print
942 it to stderr, and add it to the context. */
944 void
945 recording::context::add_error_va (location *loc, const char *fmt, va_list ap)
947 char *malloced_msg;
948 const char *errmsg;
949 bool has_ownership;
951 JIT_LOG_SCOPE (get_logger ());
953 vasprintf (&malloced_msg, fmt, ap);
954 if (malloced_msg)
956 errmsg = malloced_msg;
957 has_ownership = true;
959 else
961 errmsg = "out of memory generating error message";
962 has_ownership = false;
964 if (get_logger ())
965 get_logger ()->log ("error %i: %s", m_error_count, errmsg);
967 const char *ctxt_progname =
968 get_str_option (GCC_JIT_STR_OPTION_PROGNAME);
969 if (!ctxt_progname)
970 ctxt_progname = "libgccjit.so";
972 if (loc)
973 fprintf (stderr, "%s: %s: error: %s\n",
974 ctxt_progname,
975 loc->get_debug_string (),
976 errmsg);
977 else
978 fprintf (stderr, "%s: error: %s\n",
979 ctxt_progname,
980 errmsg);
982 if (!m_error_count)
984 m_first_error_str = const_cast <char *> (errmsg);
985 m_owns_first_error_str = has_ownership;
987 else
988 if (has_ownership)
989 free (malloced_msg);
991 m_error_count++;
994 /* Get the message for the first error that occurred on this context, or
995 NULL if no errors have occurred on it.
997 Implements the post-error-checking part of
998 gcc_jit_context_get_first_error. */
1000 const char *
1001 recording::context::get_first_error () const
1003 return m_first_error_str;
1006 /* Lazily generate and record a recording::type representing an opaque
1007 struct named "FILE".
1009 For use if client code tries to dereference the result of
1010 get_type (GCC_JIT_TYPE_FILE_PTR). */
1012 recording::type *
1013 recording::context::get_opaque_FILE_type ()
1015 if (!m_FILE_type)
1016 m_FILE_type = new_struct_type (NULL, "FILE");
1017 return m_FILE_type;
1020 /* Dump a C-like representation of the given context to the given path.
1021 If UPDATE_LOCATIONS is true, update the locations within the
1022 context's mementos to point to the dumpfile.
1024 Implements the post-error-checking part of
1025 gcc_jit_context_dump_to_file. */
1027 void
1028 recording::context::dump_to_file (const char *path, bool update_locations)
1030 int i;
1031 dump d (*this, path, update_locations);
1033 /* Forward declaration of structs and unions. */
1034 compound_type *st;
1035 FOR_EACH_VEC_ELT (m_compound_types, i, st)
1037 d.write ("%s;\n\n", st->get_debug_string ());
1040 /* Content of structs, where set. */
1041 FOR_EACH_VEC_ELT (m_compound_types, i, st)
1042 if (st->get_fields ())
1044 st->get_fields ()->write_to_dump (d);
1045 d.write ("\n");
1048 function *fn;
1049 FOR_EACH_VEC_ELT (m_functions, i, fn)
1051 fn->write_to_dump (d);
1055 /* Copy the requested dumps within this context and all ancestors into
1056 OUT. */
1058 void
1059 recording::context::get_all_requested_dumps (vec <recording::requested_dump> *out)
1061 if (m_parent_ctxt)
1062 m_parent_ctxt->get_all_requested_dumps (out);
1064 out->reserve (m_requested_dumps.length ());
1065 out->splice (m_requested_dumps);
1068 /* This is a pre-compilation check for the context (and any parents).
1070 Detect errors within the context, adding errors if any are found. */
1072 void
1073 recording::context::validate ()
1075 JIT_LOG_SCOPE (get_logger ());
1077 if (m_parent_ctxt)
1078 m_parent_ctxt->validate ();
1080 int i;
1081 function *fn;
1082 FOR_EACH_VEC_ELT (m_functions, i, fn)
1083 fn->validate ();
1086 /* The implementation of class gcc::jit::recording::memento. */
1088 /* Get a (const char *) debug description of the given memento, by
1089 calling the pure-virtual make_debug_string hook, caching the
1090 result.
1092 It is intended that this should only be called in debugging and
1093 error-handling paths, so this doesn't need to be particularly
1094 optimized. */
1096 const char *
1097 recording::memento::get_debug_string ()
1099 if (!m_debug_string)
1100 m_debug_string = make_debug_string ();
1101 return m_debug_string->c_str ();
1104 /* Default implementation of recording::memento::write_to_dump, writing
1105 an indented form of the memento's debug string to the dump. */
1107 void
1108 recording::memento::write_to_dump (dump &d)
1110 d.write(" %s\n", get_debug_string ());
1113 /* The implementation of class gcc::jit::recording::string. */
1115 /* Constructor for gcc::jit::recording::string::string, allocating a
1116 copy of the given text using new char[]. */
1118 recording::string::string (context *ctxt, const char *text)
1119 : memento (ctxt)
1121 m_len = strlen (text);
1122 m_buffer = new char[m_len + 1];
1123 strcpy (m_buffer, text);
1126 /* Destructor for gcc::jit::recording::string::string. */
1128 recording::string::~string ()
1130 delete[] m_buffer;
1133 /* Function for making gcc::jit::recording::string instances on a
1134 context via printf-style formatting.
1136 It is intended that this should only be called in debugging and
1137 error-handling paths, so this doesn't need to be particularly
1138 optimized, hence the double-copy of the string is acceptable. */
1140 recording::string *
1141 recording::string::from_printf (context *ctxt, const char *fmt, ...)
1143 va_list ap;
1144 char *buf = NULL;
1145 recording::string *result;
1147 va_start (ap, fmt);
1148 vasprintf (&buf, fmt, ap);
1149 va_end (ap);
1151 if (!buf)
1153 ctxt->add_error (NULL, "malloc failure");
1154 return NULL;
1157 result = ctxt->new_string (buf);
1158 free (buf);
1159 return result;
1162 /* Implementation of recording::memento::make_debug_string for strings,
1163 wrapping the given string in quotes and escaping as necessary. */
1165 recording::string *
1166 recording::string::make_debug_string ()
1168 /* Hack to avoid infinite recursion into strings when logging all
1169 mementos: don't re-escape strings: */
1170 if (m_buffer[0] == '"')
1171 return this;
1173 /* Wrap in quotes and do escaping etc */
1175 size_t sz = (1 /* opening quote */
1176 + (m_len * 2) /* each char might get escaped */
1177 + 1 /* closing quote */
1178 + 1); /* nil termintator */
1179 char *tmp = new char[sz];
1180 size_t len = 0;
1182 #define APPEND(CH) do { gcc_assert (len < sz); tmp[len++] = (CH); } while (0)
1183 APPEND('"'); /* opening quote */
1184 for (size_t i = 0; i < m_len ; i++)
1186 char ch = m_buffer[i];
1187 if (ch == '\t' || ch == '\n' || ch == '\\' || ch == '"')
1188 APPEND('\\');
1189 APPEND(ch);
1191 APPEND('"'); /* closing quote */
1192 #undef APPEND
1193 tmp[len] = '\0'; /* nil termintator */
1195 string *result = m_ctxt->new_string (tmp);
1197 delete[] tmp;
1198 return result;
1201 /* The implementation of class gcc::jit::recording::location. */
1203 /* Implementation of recording::memento::replay_into for locations.
1205 Create a new playback::location and store it into the
1206 recording::location's m_playback_obj field. */
1208 void
1209 recording::location::replay_into (replayer *r)
1211 m_playback_obj = r->new_location (this,
1212 m_filename->c_str (),
1213 m_line,
1214 m_column);
1217 /* Implementation of recording::memento::make_debug_string for locations,
1218 turning them into the usual form:
1219 FILENAME:LINE:COLUMN
1220 like we do when emitting diagnostics. */
1222 recording::string *
1223 recording::location::make_debug_string ()
1225 return string::from_printf (m_ctxt,
1226 "%s:%i:%i",
1227 m_filename->c_str (), m_line, m_column);
1230 /* The implementation of class gcc::jit::recording::type. */
1232 /* Given a type T, get the type T*.
1234 If this doesn't already exist, generate a new memento_of_get_pointer
1235 instance and add it to this type's context's list of mementos.
1237 Otherwise, use the cached type.
1239 Implements the post-error-checking part of
1240 gcc_jit_type_get_pointer. */
1242 recording::type *
1243 recording::type::get_pointer ()
1245 if (!m_pointer_to_this_type)
1247 m_pointer_to_this_type = new memento_of_get_pointer (this);
1248 m_ctxt->record (m_pointer_to_this_type);
1250 return m_pointer_to_this_type;
1253 /* Given a type T, get the type const T.
1255 Implements the post-error-checking part of
1256 gcc_jit_type_get_const. */
1258 recording::type *
1259 recording::type::get_const ()
1261 recording::type *result = new memento_of_get_const (this);
1262 m_ctxt->record (result);
1263 return result;
1266 /* Given a type T, get the type volatile T.
1268 Implements the post-error-checking part of
1269 gcc_jit_type_get_volatile. */
1271 recording::type *
1272 recording::type::get_volatile ()
1274 recording::type *result = new memento_of_get_volatile (this);
1275 m_ctxt->record (result);
1276 return result;
1279 /* Implementation of pure virtual hook recording::type::dereference for
1280 recording::memento_of_get_type. */
1282 recording::type *
1283 recording::memento_of_get_type::dereference ()
1285 switch (m_kind)
1287 default: gcc_unreachable ();
1289 case GCC_JIT_TYPE_VOID:
1290 return NULL;
1292 case GCC_JIT_TYPE_VOID_PTR:
1293 return m_ctxt->get_type (GCC_JIT_TYPE_VOID);
1295 case GCC_JIT_TYPE_BOOL:
1296 case GCC_JIT_TYPE_CHAR:
1297 case GCC_JIT_TYPE_SIGNED_CHAR:
1298 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1299 case GCC_JIT_TYPE_SHORT:
1300 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1301 case GCC_JIT_TYPE_INT:
1302 case GCC_JIT_TYPE_UNSIGNED_INT:
1303 case GCC_JIT_TYPE_LONG:
1304 case GCC_JIT_TYPE_UNSIGNED_LONG:
1305 case GCC_JIT_TYPE_LONG_LONG:
1306 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1307 case GCC_JIT_TYPE_FLOAT:
1308 case GCC_JIT_TYPE_DOUBLE:
1309 case GCC_JIT_TYPE_LONG_DOUBLE:
1310 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1311 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1312 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1313 /* Not a pointer: */
1314 return NULL;
1316 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1317 return m_ctxt->get_type (GCC_JIT_TYPE_CHAR)->get_const ();
1319 case GCC_JIT_TYPE_SIZE_T:
1320 /* Not a pointer: */
1321 return NULL;
1323 case GCC_JIT_TYPE_FILE_PTR:
1324 /* Give the client code back an opaque "struct FILE". */
1325 return m_ctxt->get_opaque_FILE_type ();
1329 /* Implementation of pure virtual hook recording::type::is_int for
1330 recording::memento_of_get_type. */
1332 bool
1333 recording::memento_of_get_type::is_int () const
1335 switch (m_kind)
1337 default: gcc_unreachable ();
1339 case GCC_JIT_TYPE_VOID:
1340 return false;
1342 case GCC_JIT_TYPE_VOID_PTR:
1343 return false;
1345 case GCC_JIT_TYPE_BOOL:
1346 return false;
1348 case GCC_JIT_TYPE_CHAR:
1349 case GCC_JIT_TYPE_SIGNED_CHAR:
1350 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1351 case GCC_JIT_TYPE_SHORT:
1352 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1353 case GCC_JIT_TYPE_INT:
1354 case GCC_JIT_TYPE_UNSIGNED_INT:
1355 case GCC_JIT_TYPE_LONG:
1356 case GCC_JIT_TYPE_UNSIGNED_LONG:
1357 case GCC_JIT_TYPE_LONG_LONG:
1358 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1359 return true;
1361 case GCC_JIT_TYPE_FLOAT:
1362 case GCC_JIT_TYPE_DOUBLE:
1363 case GCC_JIT_TYPE_LONG_DOUBLE:
1364 return false;
1366 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1367 return false;
1369 case GCC_JIT_TYPE_SIZE_T:
1370 return true;
1372 case GCC_JIT_TYPE_FILE_PTR:
1373 return false;
1375 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1376 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1377 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1378 return false;
1382 /* Implementation of pure virtual hook recording::type::is_float for
1383 recording::memento_of_get_type. */
1385 bool
1386 recording::memento_of_get_type::is_float () const
1388 switch (m_kind)
1390 default: gcc_unreachable ();
1392 case GCC_JIT_TYPE_VOID:
1393 return false;
1395 case GCC_JIT_TYPE_VOID_PTR:
1396 return false;
1398 case GCC_JIT_TYPE_BOOL:
1399 return false;
1401 case GCC_JIT_TYPE_CHAR:
1402 case GCC_JIT_TYPE_SIGNED_CHAR:
1403 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1404 case GCC_JIT_TYPE_SHORT:
1405 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1406 case GCC_JIT_TYPE_INT:
1407 case GCC_JIT_TYPE_UNSIGNED_INT:
1408 case GCC_JIT_TYPE_LONG:
1409 case GCC_JIT_TYPE_UNSIGNED_LONG:
1410 case GCC_JIT_TYPE_LONG_LONG:
1411 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1412 return false;
1414 case GCC_JIT_TYPE_FLOAT:
1415 case GCC_JIT_TYPE_DOUBLE:
1416 case GCC_JIT_TYPE_LONG_DOUBLE:
1417 return true;
1419 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1420 return false;
1422 case GCC_JIT_TYPE_SIZE_T:
1423 return false;
1425 case GCC_JIT_TYPE_FILE_PTR:
1426 return false;
1428 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1429 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1430 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1431 return true;
1435 /* Implementation of pure virtual hook recording::type::is_bool for
1436 recording::memento_of_get_type. */
1438 bool
1439 recording::memento_of_get_type::is_bool () const
1441 switch (m_kind)
1443 default: gcc_unreachable ();
1445 case GCC_JIT_TYPE_VOID:
1446 return false;
1448 case GCC_JIT_TYPE_VOID_PTR:
1449 return false;
1451 case GCC_JIT_TYPE_BOOL:
1452 return true;
1454 case GCC_JIT_TYPE_CHAR:
1455 case GCC_JIT_TYPE_SIGNED_CHAR:
1456 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1457 case GCC_JIT_TYPE_SHORT:
1458 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1459 case GCC_JIT_TYPE_INT:
1460 case GCC_JIT_TYPE_UNSIGNED_INT:
1461 case GCC_JIT_TYPE_LONG:
1462 case GCC_JIT_TYPE_UNSIGNED_LONG:
1463 case GCC_JIT_TYPE_LONG_LONG:
1464 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1465 return false;
1467 case GCC_JIT_TYPE_FLOAT:
1468 case GCC_JIT_TYPE_DOUBLE:
1469 case GCC_JIT_TYPE_LONG_DOUBLE:
1470 return false;
1472 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1473 return false;
1475 case GCC_JIT_TYPE_SIZE_T:
1476 return false;
1478 case GCC_JIT_TYPE_FILE_PTR:
1479 return false;
1481 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1482 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1483 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1484 return false;
1488 /* Implementation of pure virtual hook recording::memento::replay_into
1489 for recording::memento_of_get_type. */
1491 void
1492 recording::memento_of_get_type::replay_into (replayer *r)
1494 set_playback_obj (r->get_type (m_kind));
1497 /* The implementation of class gcc::jit::recording::memento_of_get_type. */
1499 /* Descriptive strings for each of enum gcc_jit_types. */
1501 static const char * const get_type_strings[] = {
1502 "void", /* GCC_JIT_TYPE_VOID */
1503 "void *", /* GCC_JIT_TYPE_VOID_PTR */
1505 "bool", /* GCC_JIT_TYPE_BOOL */
1507 "char", /* GCC_JIT_TYPE_CHAR */
1508 "signed char", /* GCC_JIT_TYPE_SIGNED_CHAR */
1509 "unsigned char", /* GCC_JIT_TYPE_UNSIGNED_CHAR */
1511 "short", /* GCC_JIT_TYPE_SHORT */
1512 "unsigned short", /* GCC_JIT_TYPE_UNSIGNED_SHORT */
1514 "int", /* GCC_JIT_TYPE_INT */
1515 "unsigned int", /* GCC_JIT_TYPE_UNSIGNED_INT */
1517 "long", /* GCC_JIT_TYPE_LONG */
1518 "unsigned long", /* GCC_JIT_TYPE_UNSIGNED_LONG, */
1520 "long long", /* GCC_JIT_TYPE_LONG_LONG */
1521 "unsigned long long", /* GCC_JIT_TYPE_UNSIGNED_LONG_LONG */
1523 "float", /* GCC_JIT_TYPE_FLOAT */
1524 "double", /* GCC_JIT_TYPE_DOUBLE */
1525 "long double", /* GCC_JIT_TYPE_LONG_DOUBLE */
1527 "const char *", /* GCC_JIT_TYPE_CONST_CHAR_PTR */
1529 "size_t", /* GCC_JIT_TYPE_SIZE_T */
1531 "FILE *", /* GCC_JIT_TYPE_FILE_PTR */
1533 "complex float", /* GCC_JIT_TYPE_COMPLEX_FLOAT */
1534 "complex double", /* GCC_JIT_TYPE_COMPLEX_DOUBLE */
1535 "complex long double" /* GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE */
1539 /* Implementation of recording::memento::make_debug_string for
1540 results of get_type, using a simple table of type names. */
1542 recording::string *
1543 recording::memento_of_get_type::make_debug_string ()
1545 return m_ctxt->new_string (get_type_strings[m_kind]);
1548 /* The implementation of class gcc::jit::recording::memento_of_get_pointer. */
1550 /* Override of default implementation of
1551 recording::type::accepts_writes_from for get_pointer.
1553 Require a pointer type, and allowing writes to
1554 (const T *) from a (T*), but not the other way around. */
1556 bool
1557 recording::memento_of_get_pointer::accepts_writes_from (type *rtype)
1559 /* Must be a pointer type: */
1560 type *rtype_points_to = rtype->is_pointer ();
1561 if (!rtype_points_to)
1562 return false;
1564 /* It's OK to assign to a (const T *) from a (T *). */
1565 return m_other_type->unqualified ()
1566 ->accepts_writes_from (rtype_points_to);
1569 /* Implementation of pure virtual hook recording::memento::replay_into
1570 for recording::memento_of_get_pointer. */
1572 void
1573 recording::memento_of_get_pointer::replay_into (replayer *)
1575 set_playback_obj (m_other_type->playback_type ()->get_pointer ());
1578 /* Implementation of recording::memento::make_debug_string for
1579 results of get_pointer, adding " *" to the underlying type,
1580 with special-casing to handle function pointer types. */
1582 recording::string *
1583 recording::memento_of_get_pointer::make_debug_string ()
1585 /* Special-case function pointer types, to put the "*" in parens between
1586 the return type and the params (for one level of dereferencing, at
1587 least). */
1588 if (function_type *fn_type = m_other_type->dyn_cast_function_type ())
1589 return fn_type->make_debug_string_with_ptr ();
1591 return string::from_printf (m_ctxt,
1592 "%s *", m_other_type->get_debug_string ());
1595 /* The implementation of class gcc::jit::recording::memento_of_get_const. */
1597 /* Implementation of pure virtual hook recording::memento::replay_into
1598 for recording::memento_of_get_const. */
1600 void
1601 recording::memento_of_get_const::replay_into (replayer *)
1603 set_playback_obj (m_other_type->playback_type ()->get_const ());
1606 /* Implementation of recording::memento::make_debug_string for
1607 results of get_const, prepending "const ". */
1609 recording::string *
1610 recording::memento_of_get_const::make_debug_string ()
1612 return string::from_printf (m_ctxt,
1613 "const %s", m_other_type->get_debug_string ());
1616 /* The implementation of class gcc::jit::recording::memento_of_get_volatile. */
1618 /* Implementation of pure virtual hook recording::memento::replay_into
1619 for recording::memento_of_get_volatile. */
1621 void
1622 recording::memento_of_get_volatile::replay_into (replayer *)
1624 set_playback_obj (m_other_type->playback_type ()->get_volatile ());
1627 /* Implementation of recording::memento::make_debug_string for
1628 results of get_volatile, prepending "volatile ". */
1630 recording::string *
1631 recording::memento_of_get_volatile::make_debug_string ()
1633 return string::from_printf (m_ctxt,
1634 "volatile %s", m_other_type->get_debug_string ());
1637 /* The implementation of class gcc::jit::recording::array_type */
1639 /* Implementation of pure virtual hook recording::type::dereference for
1640 recording::array_type. */
1642 recording::type *
1643 recording::array_type::dereference ()
1645 return m_element_type;
1648 /* Implementation of pure virtual hook recording::memento::replay_into
1649 for recording::array_type. */
1651 void
1652 recording::array_type::replay_into (replayer *r)
1654 set_playback_obj (r->new_array_type (playback_location (r, m_loc),
1655 m_element_type->playback_type (),
1656 m_num_elements));
1659 /* Implementation of recording::memento::make_debug_string for
1660 results of new_array_type. */
1662 recording::string *
1663 recording::array_type::make_debug_string ()
1665 return string::from_printf (m_ctxt,
1666 "%s[%d]",
1667 m_element_type->get_debug_string (),
1668 m_num_elements);
1671 /* The implementation of class gcc::jit::recording::function_type */
1673 /* Constructor for gcc::jit::recording::function_type. */
1675 recording::function_type::function_type (context *ctxt,
1676 type *return_type,
1677 int num_params,
1678 type **param_types,
1679 int is_variadic)
1680 : type (ctxt),
1681 m_return_type (return_type),
1682 m_param_types (),
1683 m_is_variadic (is_variadic)
1685 for (int i = 0; i< num_params; i++)
1686 m_param_types.safe_push (param_types[i]);
1689 /* Implementation of pure virtual hook recording::type::dereference for
1690 recording::function_type. */
1692 recording::type *
1693 recording::function_type::dereference ()
1695 return NULL;
1698 /* Implementation of pure virtual hook recording::memento::replay_into
1699 for recording::function_type. */
1701 void
1702 recording::function_type::replay_into (replayer *r)
1704 /* Convert m_param_types to a vec of playback type. */
1705 auto_vec <playback::type *> param_types;
1706 int i;
1707 recording::type *type;
1708 param_types.create (m_param_types.length ());
1709 FOR_EACH_VEC_ELT (m_param_types, i, type)
1710 param_types.safe_push (type->playback_type ());
1712 set_playback_obj (r->new_function_type (m_return_type->playback_type (),
1713 &param_types,
1714 m_is_variadic));
1717 /* Special-casing for make_debug_string for get_pointer results for
1718 handling (one level) of pointers to functions. */
1720 recording::string *
1721 recording::function_type::make_debug_string_with_ptr ()
1723 return make_debug_string_with ("(*) ");
1726 /* Implementation of recording::memento::make_debug_string for
1727 results of new_function_type. */
1729 recording::string *
1730 recording::function_type::make_debug_string ()
1732 return make_debug_string_with ("");
1735 /* Build a debug string representation of the form:
1737 RESULT_TYPE INSERT (PARAM_TYPES)
1739 for use when handling 0 and 1 level of indirection to this
1740 function type. */
1742 recording::string *
1743 recording::function_type::make_debug_string_with (const char *insert)
1745 /* First, build a buffer for the arguments. */
1746 /* Calculate length of said buffer. */
1747 size_t sz = 1; /* nil terminator */
1748 for (unsigned i = 0; i< m_param_types.length (); i++)
1750 sz += strlen (m_param_types[i]->get_debug_string ());
1751 sz += 2; /* ", " separator */
1753 if (m_is_variadic)
1754 sz += 5; /* ", ..." separator and ellipsis */
1756 /* Now allocate and populate the buffer. */
1757 char *argbuf = new char[sz];
1758 size_t len = 0;
1760 for (unsigned i = 0; i< m_param_types.length (); i++)
1762 strcpy (argbuf + len, m_param_types[i]->get_debug_string ());
1763 len += strlen (m_param_types[i]->get_debug_string ());
1764 if (i + 1 < m_param_types.length ())
1766 strcpy (argbuf + len, ", ");
1767 len += 2;
1770 if (m_is_variadic)
1772 if (m_param_types.length ())
1774 strcpy (argbuf + len, ", ");
1775 len += 2;
1777 strcpy (argbuf + len, "...");
1778 len += 3;
1780 argbuf[len] = '\0';
1782 /* ...and use it to get the string for the call as a whole. */
1783 string *result = string::from_printf (m_ctxt,
1784 "%s %s(%s)",
1785 m_return_type->get_debug_string (),
1786 insert,
1787 argbuf);
1789 delete[] argbuf;
1791 return result;
1794 /* The implementation of class gcc::jit::recording::field. */
1796 /* Implementation of pure virtual hook recording::memento::replay_into
1797 for recording::field. */
1799 void
1800 recording::field::replay_into (replayer *r)
1802 set_playback_obj (r->new_field (playback_location (r, m_loc),
1803 m_type->playback_type (),
1804 playback_string (m_name)));
1807 /* Override the default implementation of
1808 recording::memento::write_to_dump. Dump each field
1809 by dumping a line of the form:
1810 TYPE NAME;
1811 so that we can build up a struct/union field-byfield. */
1813 void
1814 recording::field::write_to_dump (dump &d)
1816 d.write (" %s %s;\n",
1817 m_type->get_debug_string (),
1818 m_name->c_str ());
1821 /* Implementation of recording::memento::make_debug_string for
1822 results of new_field. */
1824 recording::string *
1825 recording::field::make_debug_string ()
1827 return m_name;
1830 /* The implementation of class gcc::jit::recording::compound_type */
1832 /* The constructor for gcc::jit::recording::compound_type. */
1834 recording::compound_type::compound_type (context *ctxt,
1835 location *loc,
1836 string *name)
1837 : type (ctxt),
1838 m_loc (loc),
1839 m_name (name),
1840 m_fields (NULL)
1844 /* Set the fields of a compound type.
1846 Implements the post-error-checking part of
1847 gcc_jit_struct_set_fields, and is also used by
1848 gcc_jit_context_new_union_type. */
1850 void
1851 recording::compound_type::set_fields (location *loc,
1852 int num_fields,
1853 field **field_array)
1855 m_loc = loc;
1856 gcc_assert (NULL == m_fields);
1858 m_fields = new fields (this, num_fields, field_array);
1859 m_ctxt->record (m_fields);
1862 /* Implementation of pure virtual hook recording::type::dereference for
1863 recording::compound_type. */
1865 recording::type *
1866 recording::compound_type::dereference ()
1868 return NULL; /* not a pointer */
1871 /* The implementation of class gcc::jit::recording::struct_. */
1873 /* The constructor for gcc::jit::recording::struct_. */
1875 recording::struct_::struct_ (context *ctxt,
1876 location *loc,
1877 string *name)
1878 : compound_type (ctxt, loc, name)
1882 /* Implementation of pure virtual hook recording::memento::replay_into
1883 for recording::struct_. */
1885 void
1886 recording::struct_::replay_into (replayer *r)
1888 set_playback_obj (
1889 r->new_compound_type (playback_location (r, get_loc ()),
1890 get_name ()->c_str (),
1891 true /* is_struct */));
1894 /* Implementation of recording::memento::make_debug_string for
1895 structs. */
1897 recording::string *
1898 recording::struct_::make_debug_string ()
1900 return string::from_printf (m_ctxt,
1901 "struct %s", get_name ()->c_str ());
1904 /* The implementation of class gcc::jit::recording::union_. */
1906 /* The constructor for gcc::jit::recording::union_. */
1908 recording::union_::union_ (context *ctxt,
1909 location *loc,
1910 string *name)
1911 : compound_type (ctxt, loc, name)
1915 /* Implementation of pure virtual hook recording::memento::replay_into
1916 for recording::union_. */
1918 void
1919 recording::union_::replay_into (replayer *r)
1921 set_playback_obj (
1922 r->new_compound_type (playback_location (r, get_loc ()),
1923 get_name ()->c_str (),
1924 false /* is_struct */));
1927 /* Implementation of recording::memento::make_debug_string for
1928 unions. */
1930 recording::string *
1931 recording::union_::make_debug_string ()
1933 return string::from_printf (m_ctxt,
1934 "union %s", get_name ()->c_str ());
1937 /* The implementation of class gcc::jit::recording::fields. */
1939 /* The constructor for gcc::jit::recording::fields. */
1941 recording::fields::fields (compound_type *struct_or_union,
1942 int num_fields,
1943 field **fields)
1944 : memento (struct_or_union->m_ctxt),
1945 m_struct_or_union (struct_or_union),
1946 m_fields ()
1948 for (int i = 0; i < num_fields; i++)
1950 gcc_assert (fields[i]->get_container () == NULL);
1951 fields[i]->set_container (m_struct_or_union);
1952 m_fields.safe_push (fields[i]);
1956 /* Implementation of pure virtual hook recording::memento::replay_into
1957 for recording::fields. */
1959 void
1960 recording::fields::replay_into (replayer *)
1962 auto_vec<playback::field *> playback_fields;
1963 playback_fields.create (m_fields.length ());
1964 for (unsigned i = 0; i < m_fields.length (); i++)
1965 playback_fields.safe_push (m_fields[i]->playback_field ());
1966 m_struct_or_union->playback_compound_type ()->set_fields (&playback_fields);
1969 /* Override the default implementation of
1970 recording::memento::write_to_dump by writing a union/struct
1971 declaration of this form:
1973 struct/union NAME {
1974 TYPE_1 NAME_1;
1975 TYPE_2 NAME_2;
1976 ....
1977 TYPE_N NAME_N;
1980 to the dump. */
1982 void
1983 recording::fields::write_to_dump (dump &d)
1985 int i;
1986 field *f;
1988 d.write ("%s\n{\n", m_struct_or_union->get_debug_string ());
1989 FOR_EACH_VEC_ELT (m_fields, i, f)
1990 f->write_to_dump (d);
1991 d.write ("};\n");
1994 /* Implementation of recording::memento::make_debug_string for
1995 field tables. */
1997 recording::string *
1998 recording::fields::make_debug_string ()
2000 return string::from_printf (m_ctxt,
2001 "fields");
2004 /* The implementation of class gcc::jit::recording::rvalue. */
2006 /* Create a recording::access_field_rvalue instance and add it to
2007 the rvalue's context's list of mementos.
2009 Implements the post-error-checking part of
2010 gcc_jit_rvalue_access_field. */
2012 recording::rvalue *
2013 recording::rvalue::access_field (recording::location *loc,
2014 field *field)
2016 recording::rvalue *result =
2017 new access_field_rvalue (m_ctxt, loc, this, field);
2018 m_ctxt->record (result);
2019 return result;
2022 /* Create a recording::dereference_field_rvalue instance and add it to
2023 the rvalue's context's list of mementos.
2025 Implements the post-error-checking part of
2026 gcc_jit_rvalue_dereference_field. */
2028 recording::lvalue *
2029 recording::rvalue::dereference_field (recording::location *loc,
2030 field *field)
2032 recording::lvalue *result =
2033 new dereference_field_rvalue (m_ctxt, loc, this, field);
2034 m_ctxt->record (result);
2035 return result;
2038 /* Create a recording::dereference_rvalue instance and add it to the
2039 rvalue's context's list of mementos.
2041 Implements the post-error-checking part of
2042 gcc_jit_rvalue_dereference. */
2044 recording::lvalue *
2045 recording::rvalue::dereference (recording::location *loc)
2047 recording::lvalue *result =
2048 new dereference_rvalue (m_ctxt, loc, this);
2049 m_ctxt->record (result);
2050 return result;
2053 /* The implementation of class gcc::jit::recording::lvalue. */
2055 /* Create a recording::new_access_field_of_lvalue instance and add it to
2056 the lvalue's context's list of mementos.
2058 Implements the post-error-checking part of
2059 gcc_jit_lvalue_access_field. */
2061 recording::lvalue *
2062 recording::lvalue::access_field (recording::location *loc,
2063 field *field)
2065 recording::lvalue *result =
2066 new access_field_of_lvalue (m_ctxt, loc, this, field);
2067 m_ctxt->record (result);
2068 return result;
2071 /* Create a recording::get_address_of_lvalue instance and add it to
2072 the lvalue's context's list of mementos.
2074 Implements the post-error-checking part of
2075 gcc_jit_lvalue_get_address. */
2077 recording::rvalue *
2078 recording::lvalue::get_address (recording::location *loc)
2080 recording::rvalue *result =
2081 new get_address_of_lvalue (m_ctxt, loc, this);
2082 m_ctxt->record (result);
2083 return result;
2086 /* The implementation of class gcc::jit::recording::param. */
2088 /* Implementation of pure virtual hook recording::memento::replay_into
2089 for recording::param. */
2091 void
2092 recording::param::replay_into (replayer *r)
2094 set_playback_obj (r->new_param (playback_location (r, m_loc),
2095 m_type->playback_type (),
2096 m_name->c_str ()));
2100 /* The implementation of class gcc::jit::recording::function. */
2102 /* gcc::jit::recording::function's constructor. */
2104 recording::function::function (context *ctxt,
2105 recording::location *loc,
2106 enum gcc_jit_function_kind kind,
2107 type *return_type,
2108 recording::string *name,
2109 int num_params,
2110 recording::param **params,
2111 int is_variadic,
2112 enum built_in_function builtin_id)
2113 : memento (ctxt),
2114 m_loc (loc),
2115 m_kind (kind),
2116 m_return_type (return_type),
2117 m_name (name),
2118 m_params (),
2119 m_is_variadic (is_variadic),
2120 m_builtin_id (builtin_id),
2121 m_locals (),
2122 m_blocks ()
2124 for (int i = 0; i< num_params; i++)
2125 m_params.safe_push (params[i]);
2128 /* Implementation of pure virtual hook recording::memento::replay_into
2129 for recording::function. */
2131 void
2132 recording::function::replay_into (replayer *r)
2134 /* Convert m_params to a vec of playback param. */
2135 auto_vec <playback::param *> params;
2136 int i;
2137 recording::param *param;
2138 params.create (m_params.length ());
2139 FOR_EACH_VEC_ELT (m_params, i, param)
2140 params.safe_push (param->playback_param ());
2142 set_playback_obj (r->new_function (playback_location (r, m_loc),
2143 m_kind,
2144 m_return_type->playback_type (),
2145 m_name->c_str (),
2146 &params,
2147 m_is_variadic,
2148 m_builtin_id));
2151 /* Create a recording::local instance and add it to
2152 the functions's context's list of mementos, and to the function's
2153 list of locals.
2155 Implements the post-error-checking part of
2156 gcc_jit_function_new_local. */
2158 recording::lvalue *
2159 recording::function::new_local (recording::location *loc,
2160 type *type,
2161 const char *name)
2163 local *result = new local (this, loc, type, new_string (name));
2164 m_ctxt->record (result);
2165 m_locals.safe_push (result);
2166 return result;
2169 /* Create a recording::block instance and add it to
2170 the functions's context's list of mementos, and to the function's
2171 list of blocks.
2173 Implements the post-error-checking part of
2174 gcc_jit_function_new_block. */
2176 recording::block*
2177 recording::function::new_block (const char *name)
2179 gcc_assert (m_kind != GCC_JIT_FUNCTION_IMPORTED);
2181 recording::block *result =
2182 new recording::block (this, m_blocks.length (), new_string (name));
2183 m_ctxt->record (result);
2184 m_blocks.safe_push (result);
2185 return result;
2188 /* Override the default implementation of
2189 recording::memento::write_to_dump by dumping a C-like
2190 representation of the function; either like a prototype
2191 for GCC_JIT_FUNCTION_IMPORTED, or like a full definition for
2192 all other kinds of function. */
2194 void
2195 recording::function::write_to_dump (dump &d)
2197 switch (m_kind)
2199 default: gcc_unreachable ();
2200 case GCC_JIT_FUNCTION_EXPORTED:
2201 case GCC_JIT_FUNCTION_IMPORTED:
2202 d.write ("extern ");
2203 break;
2204 case GCC_JIT_FUNCTION_INTERNAL:
2205 d.write ("static ");
2206 break;
2207 case GCC_JIT_FUNCTION_ALWAYS_INLINE:
2208 d.write ("static inline ");
2209 break;
2211 d.write ("%s\n", m_return_type->get_debug_string ());
2213 if (d.update_locations ())
2214 m_loc = d.make_location ();
2216 d.write ("%s (", get_debug_string ());
2218 int i;
2219 recording::param *param;
2220 FOR_EACH_VEC_ELT (m_params, i, param)
2222 if (i > 0)
2223 d.write (", ");
2224 d.write ("%s %s",
2225 param->get_type ()->get_debug_string (),
2226 param->get_debug_string ());
2228 d.write (")");
2229 if (m_kind == GCC_JIT_FUNCTION_IMPORTED)
2231 d.write ("; /* (imported) */\n\n");
2233 else
2235 int i;
2236 local *var = NULL;
2237 block *b;
2238 d.write ("\n{\n");
2240 /* Write locals: */
2241 FOR_EACH_VEC_ELT (m_locals, i, var)
2242 var->write_to_dump (d);
2243 if (m_locals.length ())
2244 d.write ("\n");
2246 /* Write each block: */
2247 FOR_EACH_VEC_ELT (m_blocks, i, b)
2249 if (i > 0)
2250 d.write ("\n");
2251 b->write_to_dump (d);
2254 d.write ("}\n\n");
2258 /* Pre-compilation validation of a function, for those things we can't
2259 check until the context is (supposedly) fully-populated. */
2261 void
2262 recording::function::validate ()
2264 /* Complain about empty functions with non-void return type. */
2265 if (m_kind != GCC_JIT_FUNCTION_IMPORTED
2266 && m_return_type != m_ctxt->get_type (GCC_JIT_TYPE_VOID))
2267 if (0 == m_blocks.length ())
2268 m_ctxt->add_error (m_loc,
2269 "function %s returns non-void (type: %s)"
2270 " but has no blocks",
2271 get_debug_string (),
2272 m_return_type->get_debug_string ());
2274 /* Check that all blocks are terminated. */
2275 int num_invalid_blocks = 0;
2277 int i;
2278 block *b;
2280 FOR_EACH_VEC_ELT (m_blocks, i, b)
2281 if (!b->validate ())
2282 num_invalid_blocks++;
2285 /* Check that all blocks are reachable. */
2286 if (m_blocks.length () > 0 && 0 == num_invalid_blocks)
2288 /* Iteratively walk the graph of blocks, marking their "m_is_reachable"
2289 flag, starting at the initial block. */
2290 auto_vec<block *> worklist (m_blocks.length ());
2291 worklist.safe_push (m_blocks[0]);
2292 while (worklist.length () > 0)
2294 block *b = worklist.pop ();
2295 b->m_is_reachable = true;
2297 /* Add successor blocks that aren't yet marked to the worklist. */
2298 /* We checked that each block has a terminating statement above . */
2299 block *next1, *next2;
2300 int n = b->get_successor_blocks (&next1, &next2);
2301 switch (n)
2303 default:
2304 gcc_unreachable ();
2305 case 2:
2306 if (!next2->m_is_reachable)
2307 worklist.safe_push (next2);
2308 /* fallthrough */
2309 case 1:
2310 if (!next1->m_is_reachable)
2311 worklist.safe_push (next1);
2312 break;
2313 case 0:
2314 break;
2318 /* Now complain about any blocks that haven't been marked. */
2320 int i;
2321 block *b;
2322 FOR_EACH_VEC_ELT (m_blocks, i, b)
2323 if (!b->m_is_reachable)
2324 m_ctxt->add_error (b->get_loc (),
2325 "unreachable block: %s",
2326 b->get_debug_string ());
2331 /* Implements the post-error-checking part of
2332 gcc_jit_function_dump_to_dot. */
2334 void
2335 recording::function::dump_to_dot (const char *path)
2337 FILE *fp = fopen (path, "w");
2338 if (!fp)
2339 return;
2341 pretty_printer the_pp;
2342 the_pp.buffer->stream = fp;
2344 pretty_printer *pp = &the_pp;
2346 pp_printf (pp,
2347 "digraph %s {\n", get_debug_string ());
2349 /* Blocks: */
2351 int i;
2352 block *b;
2353 FOR_EACH_VEC_ELT (m_blocks, i, b)
2354 b->dump_to_dot (pp);
2357 /* Edges: */
2359 int i;
2360 block *b;
2361 FOR_EACH_VEC_ELT (m_blocks, i, b)
2362 b->dump_edges_to_dot (pp);
2365 pp_printf (pp, "}\n");
2366 pp_flush (pp);
2367 fclose (fp);
2370 /* Implementation of recording::memento::make_debug_string for
2371 functions. */
2373 recording::string *
2374 recording::function::make_debug_string ()
2376 return m_name;
2379 /* The implementation of class gcc::jit::recording::block. */
2381 /* Create a recording::eval instance and add it to
2382 the block's context's list of mementos, and to the block's
2383 list of statements.
2385 Implements the post-error-checking part of
2386 gcc_jit_block_add_eval. */
2388 void
2389 recording::block::add_eval (recording::location *loc,
2390 recording::rvalue *rvalue)
2392 statement *result = new eval (this, loc, rvalue);
2393 m_ctxt->record (result);
2394 m_statements.safe_push (result);
2397 /* Create a recording::assignment instance and add it to
2398 the block's context's list of mementos, and to the block's
2399 list of statements.
2401 Implements the post-error-checking part of
2402 gcc_jit_block_add_assignment. */
2404 void
2405 recording::block::add_assignment (recording::location *loc,
2406 recording::lvalue *lvalue,
2407 recording::rvalue *rvalue)
2409 statement *result = new assignment (this, loc, lvalue, rvalue);
2410 m_ctxt->record (result);
2411 m_statements.safe_push (result);
2414 /* Create a recording::assignment_op instance and add it to
2415 the block's context's list of mementos, and to the block's
2416 list of statements.
2418 Implements the post-error-checking part of
2419 gcc_jit_block_add_assignment_op. */
2421 void
2422 recording::block::add_assignment_op (recording::location *loc,
2423 recording::lvalue *lvalue,
2424 enum gcc_jit_binary_op op,
2425 recording::rvalue *rvalue)
2427 statement *result = new assignment_op (this, loc, lvalue, op, rvalue);
2428 m_ctxt->record (result);
2429 m_statements.safe_push (result);
2432 /* Create a recording::comment instance and add it to
2433 the block's context's list of mementos, and to the block's
2434 list of statements.
2436 Implements the post-error-checking part of
2437 gcc_jit_block_add_comment. */
2439 void
2440 recording::block::add_comment (recording::location *loc,
2441 const char *text)
2443 statement *result = new comment (this, loc, new_string (text));
2444 m_ctxt->record (result);
2445 m_statements.safe_push (result);
2448 /* Create a recording::end_with_conditional instance and add it to
2449 the block's context's list of mementos, and to the block's
2450 list of statements.
2452 Implements the post-error-checking part of
2453 gcc_jit_block_end_with_conditional. */
2455 void
2456 recording::block::end_with_conditional (recording::location *loc,
2457 recording::rvalue *boolval,
2458 recording::block *on_true,
2459 recording::block *on_false)
2461 statement *result = new conditional (this, loc, boolval, on_true, on_false);
2462 m_ctxt->record (result);
2463 m_statements.safe_push (result);
2464 m_has_been_terminated = true;
2467 /* Create a recording::end_with_jump instance and add it to
2468 the block's context's list of mementos, and to the block's
2469 list of statements.
2471 Implements the post-error-checking part of
2472 gcc_jit_block_end_with_jump. */
2474 void
2475 recording::block::end_with_jump (recording::location *loc,
2476 recording::block *target)
2478 statement *result = new jump (this, loc, target);
2479 m_ctxt->record (result);
2480 m_statements.safe_push (result);
2481 m_has_been_terminated = true;
2484 /* Create a recording::end_with_return instance and add it to
2485 the block's context's list of mementos, and to the block's
2486 list of statements.
2488 Implements the post-error-checking parts of
2489 gcc_jit_block_end_with_return and
2490 gcc_jit_block_end_with_void_return. */
2492 void
2493 recording::block::end_with_return (recording::location *loc,
2494 recording::rvalue *rvalue)
2496 /* This is used by both gcc_jit_function_add_return and
2497 gcc_jit_function_add_void_return; rvalue will be non-NULL for
2498 the former and NULL for the latter. */
2499 statement *result = new return_ (this, loc, rvalue);
2500 m_ctxt->record (result);
2501 m_statements.safe_push (result);
2502 m_has_been_terminated = true;
2505 /* Override the default implementation of
2506 recording::memento::write_to_dump for blocks by writing
2507 an unindented block name as a label, followed by the indented
2508 statements:
2510 BLOCK_NAME:
2511 STATEMENT_1;
2512 STATEMENT_2;
2514 STATEMENT_N; */
2516 void
2517 recording::block::write_to_dump (dump &d)
2519 d.write ("%s:\n", get_debug_string ());
2521 int i;
2522 statement *s;
2523 FOR_EACH_VEC_ELT (m_statements, i, s)
2524 s->write_to_dump (d);
2527 /* Validate a block by ensuring that it has been terminated. */
2529 bool
2530 recording::block::validate ()
2532 if (!has_been_terminated ())
2534 statement *stmt = get_last_statement ();
2535 location *loc = stmt ? stmt->get_loc () : NULL;
2536 m_func->get_context ()->add_error (loc,
2537 "unterminated block in %s: %s",
2538 m_func->get_debug_string (),
2539 get_debug_string ());
2540 return false;
2543 return true;
2546 /* Get the source-location of a block by using that of the first
2547 statement within it, if any. */
2549 recording::location *
2550 recording::block::get_loc () const
2552 recording::statement *stmt = get_first_statement ();
2553 if (stmt)
2554 return stmt->get_loc ();
2555 else
2556 return NULL;
2559 /* Get the first statement within a block, if any. */
2561 recording::statement *
2562 recording::block::get_first_statement () const
2564 if (m_statements.length ())
2565 return m_statements[0];
2566 else
2567 return NULL;
2570 /* Get the last statement within a block, if any. */
2572 recording::statement *
2573 recording::block::get_last_statement () const
2575 if (m_statements.length ())
2576 return m_statements[m_statements.length () - 1];
2577 else
2578 return NULL;
2581 /* Assuming that this block has been terminated, get the number of
2582 successor blocks, which will be 0, 1 or 2, for return, unconditional
2583 jump, and conditional jump respectively.
2584 NEXT1 and NEXT2 must be non-NULL. The first successor block (if any)
2585 is written to NEXT1, and the second (if any) to NEXT2.
2587 Used when validating functions, and when dumping dot representations
2588 of them. */
2591 recording::block::get_successor_blocks (block **next1, block **next2) const
2593 gcc_assert (m_has_been_terminated);
2594 gcc_assert (next1);
2595 gcc_assert (next2);
2596 statement *last_statement = get_last_statement ();
2597 gcc_assert (last_statement);
2598 return last_statement->get_successor_blocks (next1, next2);
2601 /* Implementation of pure virtual hook recording::memento::replay_into
2602 for recording::block. */
2604 void
2605 recording::block::replay_into (replayer *)
2607 set_playback_obj (m_func->playback_function ()
2608 ->new_block (playback_string (m_name)));
2611 /* Implementation of recording::memento::make_debug_string for
2612 blocks. */
2614 recording::string *
2615 recording::block::make_debug_string ()
2617 if (m_name)
2618 return m_name;
2619 else
2620 return string::from_printf (m_ctxt,
2621 "<UNNAMED BLOCK %p>",
2622 (void *)this);
2625 /* Dump a block in graphviz form into PP, capturing the block name (if
2626 any) and the statements. */
2628 void
2629 recording::block::dump_to_dot (pretty_printer *pp)
2631 pp_printf (pp,
2632 ("\tblock_%d "
2633 "[shape=record,style=filled,fillcolor=white,label=\"{"),
2634 m_index);
2635 pp_write_text_to_stream (pp);
2636 if (m_name)
2638 pp_string (pp, m_name->c_str ());
2639 pp_string (pp, ":");
2640 pp_newline (pp);
2641 pp_write_text_as_dot_label_to_stream (pp, true /*for_record*/);
2644 int i;
2645 statement *s;
2646 FOR_EACH_VEC_ELT (m_statements, i, s)
2648 pp_string (pp, s->get_debug_string ());
2649 pp_newline (pp);
2650 pp_write_text_as_dot_label_to_stream (pp, true /*for_record*/);
2653 pp_printf (pp,
2654 "}\"];\n\n");
2655 pp_flush (pp);
2658 /* Dump the out-edges of the block in graphviz form into PP. */
2660 void
2661 recording::block::dump_edges_to_dot (pretty_printer *pp)
2663 block *next[2];
2664 int num_succs = get_successor_blocks (&next[0], &next[1]);
2665 for (int i = 0; i < num_succs; i++)
2666 pp_printf (pp,
2667 "\tblock_%d:s -> block_%d:n;\n",
2668 m_index, next[i]->m_index);
2671 /* The implementation of class gcc::jit::recording::global. */
2673 /* Implementation of pure virtual hook recording::memento::replay_into
2674 for recording::global. */
2676 void
2677 recording::global::replay_into (replayer *r)
2679 set_playback_obj (r->new_global (playback_location (r, m_loc),
2680 m_type->playback_type (),
2681 playback_string (m_name)));
2684 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_int. */
2686 /* Implementation of pure virtual hook recording::memento::replay_into
2687 for recording::memento_of_new_rvalue_from_int. */
2689 void
2690 recording::memento_of_new_rvalue_from_int::replay_into (replayer *r)
2692 set_playback_obj (r->new_rvalue_from_int (m_type->playback_type (),
2693 m_value));
2696 /* Implementation of recording::memento::make_debug_string for
2697 rvalue_from_int, rendering it as
2698 (TYPE)LITERAL
2699 e.g.
2700 "(int)42". */
2702 recording::string *
2703 recording::memento_of_new_rvalue_from_int::make_debug_string ()
2705 return string::from_printf (m_ctxt,
2706 "(%s)%i",
2707 m_type->get_debug_string (),
2708 m_value);
2711 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_double. */
2713 /* Implementation of pure virtual hook recording::memento::replay_into
2714 for recording::memento_of_new_rvalue_from_double. */
2716 void
2717 recording::memento_of_new_rvalue_from_double::replay_into (replayer *r)
2719 set_playback_obj (r->new_rvalue_from_double (m_type->playback_type (),
2720 m_value));
2723 /* Implementation of recording::memento::make_debug_string for
2724 rvalue_from_double, rendering it as
2725 (TYPE)LITERAL
2726 e.g.
2727 "(float)42.0". */
2729 recording::string *
2730 recording::memento_of_new_rvalue_from_double::make_debug_string ()
2732 return string::from_printf (m_ctxt,
2733 "(%s)%f",
2734 m_type->get_debug_string (),
2735 m_value);
2738 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_ptr. */
2740 /* Implementation of pure virtual hook recording::memento::replay_into
2741 for recording::memento_of_new_rvalue_from_ptr. */
2743 void
2744 recording::memento_of_new_rvalue_from_ptr::replay_into (replayer *r)
2746 set_playback_obj (r->new_rvalue_from_ptr (m_type->playback_type (),
2747 m_value));
2750 /* Implementation of recording::memento::make_debug_string for
2751 rvalue_from_ptr, rendering it as
2752 (TYPE)HEX
2753 e.g.
2754 "(int *)0xdeadbeef"
2756 Zero is rendered as NULL e.g.
2757 "(int *)NULL". */
2759 recording::string *
2760 recording::memento_of_new_rvalue_from_ptr::make_debug_string ()
2762 if (m_value != NULL)
2763 return string::from_printf (m_ctxt,
2764 "(%s)%p",
2765 m_type->get_debug_string (), m_value);
2766 else
2767 return string::from_printf (m_ctxt,
2768 "(%s)NULL",
2769 m_type->get_debug_string ());
2772 /* The implementation of class gcc::jit::recording::memento_of_new_string_literal. */
2774 /* Implementation of pure virtual hook recording::memento::replay_into
2775 for recording::memento_of_new_string_literal. */
2777 void
2778 recording::memento_of_new_string_literal::replay_into (replayer *r)
2780 set_playback_obj (r->new_string_literal (m_value->c_str ()));
2783 /* Implementation of recording::memento::make_debug_string for
2784 string literals. */
2786 recording::string *
2787 recording::memento_of_new_string_literal::make_debug_string ()
2789 return string::from_printf (m_ctxt,
2790 m_value->get_debug_string ());
2793 /* The implementation of class gcc::jit::recording::unary_op. */
2795 /* Implementation of pure virtual hook recording::memento::replay_into
2796 for recording::unary_op. */
2798 void
2799 recording::unary_op::replay_into (replayer *r)
2801 set_playback_obj (r->new_unary_op (playback_location (r, m_loc),
2802 m_op,
2803 get_type ()->playback_type (),
2804 m_a->playback_rvalue ()));
2807 /* Implementation of recording::memento::make_debug_string for
2808 unary ops. */
2810 static const char * const unary_op_strings[] = {
2811 "-", /* GCC_JIT_UNARY_OP_MINUS */
2812 "~", /* GCC_JIT_UNARY_OP_BITWISE_NEGATE */
2813 "!", /* GCC_JIT_UNARY_OP_LOGICAL_NEGATE */
2814 "abs ", /* GCC_JIT_UNARY_OP_ABS */
2817 recording::string *
2818 recording::unary_op::make_debug_string ()
2820 return string::from_printf (m_ctxt,
2821 "%s(%s)",
2822 unary_op_strings[m_op],
2823 m_a->get_debug_string ());
2826 /* The implementation of class gcc::jit::recording::binary_op. */
2828 /* Implementation of pure virtual hook recording::memento::replay_into
2829 for recording::binary_op. */
2831 void
2832 recording::binary_op::replay_into (replayer *r)
2834 set_playback_obj (r->new_binary_op (playback_location (r, m_loc),
2835 m_op,
2836 get_type ()->playback_type (),
2837 m_a->playback_rvalue (),
2838 m_b->playback_rvalue ()));
2841 /* Implementation of recording::memento::make_debug_string for
2842 binary ops. */
2844 static const char * const binary_op_strings[] = {
2845 "+", /* GCC_JIT_BINARY_OP_PLUS */
2846 "-", /* GCC_JIT_BINARY_OP_MINUS */
2847 "*", /* GCC_JIT_BINARY_OP_MULT */
2848 "/", /* GCC_JIT_BINARY_OP_DIVIDE */
2849 "%", /* GCC_JIT_BINARY_OP_MODULO */
2850 "&", /* GCC_JIT_BINARY_OP_BITWISE_AND */
2851 "^", /* GCC_JIT_BINARY_OP_BITWISE_XOR */
2852 "|", /* GCC_JIT_BINARY_OP_BITWISE_OR */
2853 "&&", /* GCC_JIT_BINARY_OP_LOGICAL_AND */
2854 "||", /* GCC_JIT_BINARY_OP_LOGICAL_OR */
2855 "<<", /* GCC_JIT_BINARY_OP_LSHIFT */
2856 ">>", /* GCC_JIT_BINARY_OP_RSHIFT */
2859 recording::string *
2860 recording::binary_op::make_debug_string ()
2862 return string::from_printf (m_ctxt,
2863 "%s %s %s",
2864 m_a->get_debug_string (),
2865 binary_op_strings[m_op],
2866 m_b->get_debug_string ());
2869 /* The implementation of class gcc::jit::recording::comparison. */
2871 /* Implementation of recording::memento::make_debug_string for
2872 comparisons. */
2874 static const char * const comparison_strings[] =
2876 "==", /* GCC_JIT_COMPARISON_EQ */
2877 "!=", /* GCC_JIT_COMPARISON_NE */
2878 "<", /* GCC_JIT_COMPARISON_LT */
2879 "<=", /* GCC_JIT_COMPARISON_LE */
2880 ">", /* GCC_JIT_COMPARISON_GT */
2881 ">=", /* GCC_JIT_COMPARISON_GE */
2884 recording::string *
2885 recording::comparison::make_debug_string ()
2887 return string::from_printf (m_ctxt,
2888 "%s %s %s",
2889 m_a->get_debug_string (),
2890 comparison_strings[m_op],
2891 m_b->get_debug_string ());
2894 /* Implementation of pure virtual hook recording::memento::replay_into
2895 for recording::comparison. */
2897 void
2898 recording::comparison::replay_into (replayer *r)
2900 set_playback_obj (r->new_comparison (playback_location (r, m_loc),
2901 m_op,
2902 m_a->playback_rvalue (),
2903 m_b->playback_rvalue ()));
2906 /* Implementation of pure virtual hook recording::memento::replay_into
2907 for recording::cast. */
2909 void
2910 recording::cast::replay_into (replayer *r)
2912 set_playback_obj (r->new_cast (playback_location (r, m_loc),
2913 m_rvalue->playback_rvalue (),
2914 get_type ()->playback_type ()));
2917 /* Implementation of recording::memento::make_debug_string for
2918 casts. */
2920 recording::string *
2921 recording::cast::make_debug_string ()
2923 return string::from_printf (m_ctxt,
2924 "(%s)%s",
2925 get_type ()->get_debug_string (),
2926 m_rvalue->get_debug_string ());
2929 /* The implementation of class gcc::jit::recording::call. */
2931 /* The constructor for gcc::jit::recording::call. */
2933 recording::call::call (recording::context *ctxt,
2934 recording::location *loc,
2935 recording::function *func,
2936 int numargs,
2937 rvalue **args)
2938 : rvalue (ctxt, loc, func->get_return_type ()),
2939 m_func (func),
2940 m_args ()
2942 for (int i = 0; i< numargs; i++)
2943 m_args.safe_push (args[i]);
2946 /* Implementation of pure virtual hook recording::memento::replay_into
2947 for recording::call. */
2949 void
2950 recording::call::replay_into (replayer *r)
2952 auto_vec<playback::rvalue *> playback_args;
2953 playback_args.create (m_args.length ());
2954 for (unsigned i = 0; i< m_args.length (); i++)
2955 playback_args.safe_push (m_args[i]->playback_rvalue ());
2957 set_playback_obj (r->new_call (playback_location (r, m_loc),
2958 m_func->playback_function (),
2959 &playback_args));
2962 /* Implementation of recording::memento::make_debug_string for
2963 function calls. */
2965 recording::string *
2966 recording::call::make_debug_string ()
2968 /* First, build a buffer for the arguments. */
2969 /* Calculate length of said buffer. */
2970 size_t sz = 1; /* nil terminator */
2971 for (unsigned i = 0; i< m_args.length (); i++)
2973 sz += strlen (m_args[i]->get_debug_string ());
2974 sz += 2; /* ", " separator */
2977 /* Now allocate and populate the buffer. */
2978 char *argbuf = new char[sz];
2979 size_t len = 0;
2981 for (unsigned i = 0; i< m_args.length (); i++)
2983 strcpy (argbuf + len, m_args[i]->get_debug_string ());
2984 len += strlen (m_args[i]->get_debug_string ());
2985 if (i + 1 < m_args.length ())
2987 strcpy (argbuf + len, ", ");
2988 len += 2;
2991 argbuf[len] = '\0';
2993 /* ...and use it to get the string for the call as a whole. */
2994 string *result = string::from_printf (m_ctxt,
2995 "%s (%s)",
2996 m_func->get_debug_string (),
2997 argbuf);
2999 delete[] argbuf;
3001 return result;
3004 /* The implementation of class gcc::jit::recording::call_through_ptr. */
3006 /* The constructor for recording::call_through_ptr. */
3008 recording::call_through_ptr::call_through_ptr (recording::context *ctxt,
3009 recording::location *loc,
3010 recording::rvalue *fn_ptr,
3011 int numargs,
3012 rvalue **args)
3013 : rvalue (ctxt, loc,
3014 fn_ptr->get_type ()->dereference ()
3015 ->as_a_function_type ()->get_return_type ()),
3016 m_fn_ptr (fn_ptr),
3017 m_args ()
3019 for (int i = 0; i< numargs; i++)
3020 m_args.safe_push (args[i]);
3023 /* Implementation of pure virtual hook recording::memento::replay_into
3024 for recording::call_through_ptr. */
3026 void
3027 recording::call_through_ptr::replay_into (replayer *r)
3029 auto_vec<playback::rvalue *> playback_args;
3030 playback_args.create (m_args.length ());
3031 for (unsigned i = 0; i< m_args.length (); i++)
3032 playback_args.safe_push (m_args[i]->playback_rvalue ());
3034 set_playback_obj (r->new_call_through_ptr (playback_location (r, m_loc),
3035 m_fn_ptr->playback_rvalue (),
3036 &playback_args));
3039 /* Implementation of recording::memento::make_debug_string for
3040 calls through function ptrs. */
3042 recording::string *
3043 recording::call_through_ptr::make_debug_string ()
3045 /* First, build a buffer for the arguments. */
3046 /* Calculate length of said buffer. */
3047 size_t sz = 1; /* nil terminator */
3048 for (unsigned i = 0; i< m_args.length (); i++)
3050 sz += strlen (m_args[i]->get_debug_string ());
3051 sz += 2; /* ", " separator */
3054 /* Now allocate and populate the buffer. */
3055 char *argbuf = new char[sz];
3056 size_t len = 0;
3058 for (unsigned i = 0; i< m_args.length (); i++)
3060 strcpy (argbuf + len, m_args[i]->get_debug_string ());
3061 len += strlen (m_args[i]->get_debug_string ());
3062 if (i + 1 < m_args.length ())
3064 strcpy (argbuf + len, ", ");
3065 len += 2;
3068 argbuf[len] = '\0';
3070 /* ...and use it to get the string for the call as a whole. */
3071 string *result = string::from_printf (m_ctxt,
3072 "%s (%s)",
3073 m_fn_ptr->get_debug_string (),
3074 argbuf);
3076 delete[] argbuf;
3078 return result;
3081 /* The implementation of class gcc::jit::recording::array_access. */
3083 /* Implementation of pure virtual hook recording::memento::replay_into
3084 for recording::array_access. */
3086 void
3087 recording::array_access::replay_into (replayer *r)
3089 set_playback_obj (
3090 r->new_array_access (playback_location (r, m_loc),
3091 m_ptr->playback_rvalue (),
3092 m_index->playback_rvalue ()));
3095 /* Implementation of recording::memento::make_debug_string for
3096 array accesses. */
3098 recording::string *
3099 recording::array_access::make_debug_string ()
3101 return string::from_printf (m_ctxt,
3102 "%s[%s]",
3103 m_ptr->get_debug_string (),
3104 m_index->get_debug_string ());
3107 /* The implementation of class gcc::jit::recording::access_field_of_lvalue. */
3109 /* Implementation of pure virtual hook recording::memento::replay_into
3110 for recording::access_field_of_lvalue. */
3112 void
3113 recording::access_field_of_lvalue::replay_into (replayer *r)
3115 set_playback_obj (
3116 m_lvalue->playback_lvalue ()
3117 ->access_field (playback_location (r, m_loc),
3118 m_field->playback_field ()));
3122 /* Implementation of recording::memento::make_debug_string for
3123 accessing a field of an lvalue. */
3125 recording::string *
3126 recording::access_field_of_lvalue::make_debug_string ()
3128 return string::from_printf (m_ctxt,
3129 "%s.%s",
3130 m_lvalue->get_debug_string (),
3131 m_field->get_debug_string ());
3134 /* The implementation of class gcc::jit::recording::access_field_rvalue. */
3136 /* Implementation of pure virtual hook recording::memento::replay_into
3137 for recording::access_field_rvalue. */
3139 void
3140 recording::access_field_rvalue::replay_into (replayer *r)
3142 set_playback_obj (
3143 m_rvalue->playback_rvalue ()
3144 ->access_field (playback_location (r, m_loc),
3145 m_field->playback_field ()));
3148 /* Implementation of recording::memento::make_debug_string for
3149 accessing a field of an rvalue. */
3151 recording::string *
3152 recording::access_field_rvalue::make_debug_string ()
3154 return string::from_printf (m_ctxt,
3155 "%s.%s",
3156 m_rvalue->get_debug_string (),
3157 m_field->get_debug_string ());
3160 /* The implementation of class
3161 gcc::jit::recording::dereference_field_rvalue. */
3163 /* Implementation of pure virtual hook recording::memento::replay_into
3164 for recording::dereference_field_rvalue. */
3166 void
3167 recording::dereference_field_rvalue::replay_into (replayer *r)
3169 set_playback_obj (
3170 m_rvalue->playback_rvalue ()->
3171 dereference_field (playback_location (r, m_loc),
3172 m_field->playback_field ()));
3175 /* Implementation of recording::memento::make_debug_string for
3176 dereferencing a field of an rvalue. */
3178 recording::string *
3179 recording::dereference_field_rvalue::make_debug_string ()
3181 return string::from_printf (m_ctxt,
3182 "%s->%s",
3183 m_rvalue->get_debug_string (),
3184 m_field->get_debug_string ());
3187 /* The implementation of class gcc::jit::recording::dereference_rvalue. */
3189 /* Implementation of pure virtual hook recording::memento::replay_into
3190 for recording::dereference_rvalue. */
3192 void
3193 recording::dereference_rvalue::replay_into (replayer *r)
3195 set_playback_obj (
3196 m_rvalue->playback_rvalue ()->
3197 dereference (playback_location (r, m_loc)));
3200 /* Implementation of recording::memento::make_debug_string for
3201 dereferencing an rvalue. */
3203 recording::string *
3204 recording::dereference_rvalue::make_debug_string ()
3206 return string::from_printf (m_ctxt,
3207 "*%s",
3208 m_rvalue->get_debug_string ());
3211 /* The implementation of class gcc::jit::recording::get_address_of_lvalue. */
3213 /* Implementation of pure virtual hook recording::memento::replay_into
3214 for recording::get_address_of_lvalue. */
3216 void
3217 recording::get_address_of_lvalue::replay_into (replayer *r)
3219 set_playback_obj (
3220 m_lvalue->playback_lvalue ()->
3221 get_address (playback_location (r, m_loc)));
3224 /* Implementation of recording::memento::make_debug_string for
3225 getting the address of an lvalue. */
3227 recording::string *
3228 recording::get_address_of_lvalue::make_debug_string ()
3230 return string::from_printf (m_ctxt,
3231 "&%s",
3232 m_lvalue->get_debug_string ());
3235 /* The implementation of class gcc::jit::recording::local. */
3237 /* Implementation of pure virtual hook recording::memento::replay_into
3238 for recording::local. */
3240 void
3241 recording::local::replay_into (replayer *r)
3243 set_playback_obj (
3244 m_func->playback_function ()
3245 ->new_local (playback_location (r, m_loc),
3246 m_type->playback_type (),
3247 playback_string (m_name)));
3250 /* Override the default implementation of
3251 recording::memento::write_to_dump for locals by writing
3252 TYPE NAME;
3253 for use at the top of the function body as if it were a
3254 declaration. */
3256 void
3257 recording::local::write_to_dump (dump &d)
3259 if (d.update_locations ())
3260 m_loc = d.make_location ();
3261 d.write(" %s %s;\n",
3262 m_type->get_debug_string (),
3263 get_debug_string ());
3266 /* The implementation of class gcc::jit::recording::statement. */
3268 /* We poison the default implementation of
3269 gcc::jit::recording::statement::get_successor_blocks
3270 since this vfunc must only ever be called on terminator
3271 statements. */
3274 recording::statement::get_successor_blocks (block **/*out_next1*/,
3275 block **/*out_next2*/) const
3277 /* The base class implementation is for non-terminating statements,
3278 and thus should never be called. */
3279 gcc_unreachable ();
3280 return 0;
3283 /* Extend the default implementation of
3284 recording::memento::write_to_dump for statements by (if requested)
3285 updating the location of the statement to the current location in
3286 the dumpfile. */
3288 void
3289 recording::statement::write_to_dump (dump &d)
3291 memento::write_to_dump (d);
3292 if (d.update_locations ())
3293 m_loc = d.make_location ();
3296 /* The implementation of class gcc::jit::recording::eval. */
3298 /* Implementation of pure virtual hook recording::memento::replay_into
3299 for recording::eval. */
3301 void
3302 recording::eval::replay_into (replayer *r)
3304 playback_block (get_block ())
3305 ->add_eval (playback_location (r),
3306 m_rvalue->playback_rvalue ());
3309 /* Implementation of recording::memento::make_debug_string for
3310 an eval statement. */
3312 recording::string *
3313 recording::eval::make_debug_string ()
3315 return string::from_printf (m_ctxt,
3316 "(void)%s;",
3317 m_rvalue->get_debug_string ());
3320 /* The implementation of class gcc::jit::recording::assignment. */
3322 /* Implementation of pure virtual hook recording::memento::replay_into
3323 for recording::assignment. */
3325 void
3326 recording::assignment::replay_into (replayer *r)
3328 playback_block (get_block ())
3329 ->add_assignment (playback_location (r),
3330 m_lvalue->playback_lvalue (),
3331 m_rvalue->playback_rvalue ());
3334 /* Implementation of recording::memento::make_debug_string for
3335 an assignment statement. */
3337 recording::string *
3338 recording::assignment::make_debug_string ()
3340 return string::from_printf (m_ctxt,
3341 "%s = %s;",
3342 m_lvalue->get_debug_string (),
3343 m_rvalue->get_debug_string ());
3346 /* The implementation of class gcc::jit::recording::assignment_op. */
3348 /* Implementation of pure virtual hook recording::memento::replay_into
3349 for recording::assignment_op. */
3351 void
3352 recording::assignment_op::replay_into (replayer *r)
3354 playback::type *result_type =
3355 m_lvalue->playback_lvalue ()->get_type ();
3357 playback::rvalue *binary_op =
3358 r->new_binary_op (playback_location (r),
3359 m_op,
3360 result_type,
3361 m_lvalue->playback_rvalue (),
3362 m_rvalue->playback_rvalue ());
3364 playback_block (get_block ())
3365 ->add_assignment (playback_location (r),
3366 m_lvalue->playback_lvalue (),
3367 binary_op);
3370 /* Implementation of recording::memento::make_debug_string for
3371 an assignment_op statement. */
3373 recording::string *
3374 recording::assignment_op::make_debug_string ()
3376 return string::from_printf (m_ctxt,
3377 "%s %s= %s;",
3378 m_lvalue->get_debug_string (),
3379 binary_op_strings[m_op],
3380 m_rvalue->get_debug_string ());
3383 /* The implementation of class gcc::jit::recording::comment. */
3385 /* Implementation of pure virtual hook recording::memento::replay_into
3386 for recording::comment. */
3388 void
3389 recording::comment::replay_into (replayer *r)
3391 playback_block (get_block ())
3392 ->add_comment (playback_location (r),
3393 m_text->c_str ());
3396 /* Implementation of recording::memento::make_debug_string for
3397 a comment "statement". */
3399 recording::string *
3400 recording::comment::make_debug_string ()
3402 return string::from_printf (m_ctxt,
3403 "/* %s */",
3404 m_text->c_str ());
3407 /* The implementation of class gcc::jit::recording::conditional. */
3409 /* Implementation of pure virtual hook recording::memento::replay_into
3410 for recording::conditional. */
3412 void
3413 recording::conditional::replay_into (replayer *r)
3415 playback_block (get_block ())
3416 ->add_conditional (playback_location (r),
3417 m_boolval->playback_rvalue (),
3418 playback_block (m_on_true),
3419 playback_block (m_on_false));
3422 /* Override the poisoned default implementation of
3423 gcc::jit::recording::statement::get_successor_blocks
3425 A conditional jump has 2 successor blocks. */
3428 recording::conditional::get_successor_blocks (block **out_next1,
3429 block **out_next2) const
3431 *out_next1 = m_on_true;
3432 *out_next2 = m_on_false;
3433 return 2;
3436 /* Implementation of recording::memento::make_debug_string for
3437 a conditional jump statement. */
3439 recording::string *
3440 recording::conditional::make_debug_string ()
3442 if (m_on_false)
3443 return string::from_printf (m_ctxt,
3444 "if (%s) goto %s; else goto %s;",
3445 m_boolval->get_debug_string (),
3446 m_on_true->get_debug_string (),
3447 m_on_false->get_debug_string ());
3448 else
3449 return string::from_printf (m_ctxt,
3450 "if (%s) goto %s;",
3451 m_boolval->get_debug_string (),
3452 m_on_true->get_debug_string ());
3455 /* The implementation of class gcc::jit::recording::jump. */
3457 /* Implementation of pure virtual hook recording::memento::replay_into
3458 for recording::jump. */
3460 void
3461 recording::jump::replay_into (replayer *r)
3463 playback_block (get_block ())
3464 ->add_jump (playback_location (r),
3465 m_target->playback_block ());
3468 /* Override the poisoned default implementation of
3469 gcc::jit::recording::statement::get_successor_blocks
3471 An unconditional jump has 1 successor block. */
3474 recording::jump::get_successor_blocks (block **out_next1,
3475 block **/*out_next2*/) const
3477 *out_next1 = m_target;
3478 return 1;
3481 /* Implementation of recording::memento::make_debug_string for
3482 a unconditional jump statement. */
3484 recording::string *
3485 recording::jump::make_debug_string ()
3487 return string::from_printf (m_ctxt,
3488 "goto %s;",
3489 m_target->get_debug_string ());
3492 /* The implementation of class gcc::jit::recording::return_. */
3494 /* Implementation of pure virtual hook recording::memento::replay_into
3495 for recording::return_. */
3497 void
3498 recording::return_::replay_into (replayer *r)
3500 playback_block (get_block ())
3501 ->add_return (playback_location (r),
3502 m_rvalue ? m_rvalue->playback_rvalue () : NULL);
3505 /* Override the poisoned default implementation of
3506 gcc::jit::recording::statement::get_successor_blocks
3508 A return statement has no successor block. */
3511 recording::return_::get_successor_blocks (block **/*out_next1*/,
3512 block **/*out_next2*/) const
3514 return 0;
3517 /* Implementation of recording::memento::make_debug_string for
3518 a return statement (covers both those with and without rvalues). */
3520 recording::string *
3521 recording::return_::make_debug_string ()
3523 if (m_rvalue)
3524 return string::from_printf (m_ctxt,
3525 "return %s;",
3526 m_rvalue->get_debug_string ());
3527 else
3528 return string::from_printf (m_ctxt,
3529 "return;");
3532 } // namespace gcc::jit
3534 } // namespace gcc