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)
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/>. */
23 #include "coretypes.h"
27 #include "pretty-print.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"
42 dump::dump (recording::context
&ctxt
,
44 bool update_locations
)
46 m_filename (filename
),
47 m_update_locations (update_locations
),
51 m_file
= fopen (filename
, "w");
54 "error opening dump file %s for writing: %s",
63 int err
= fclose (m_file
);
65 m_ctxt
.add_error (NULL
,
66 "error closing dump file %s: %s",
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. */
78 dump::write (const char *fmt
, ...)
83 /* If there was an error opening the file, we've already reported it.
84 Don't attempt further work. */
89 vasprintf (&buf
, fmt
, ap
);
94 m_ctxt
.add_error (NULL
, "malloc failure writing to dumpfile %s",
99 if (fwrite (buf
, strlen (buf
), 1, m_file
) != 1)
100 m_ctxt
.add_error (NULL
, "error writing to dump file %s",
103 /* Update line/column: */
104 for (const char *ptr
= buf
; *ptr
; ptr
++)
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 /**********************************************************************
129 **********************************************************************/
131 /* Get the playback::location for the given recording::location,
132 handling a NULL input with a NULL output. */
135 recording::playback_location (replayer
*r
, recording::location
*loc
)
138 return loc
->playback_location (r
);
143 /* Get a const char * for the given recording::string
144 handling a NULL input with a NULL output. */
147 recording::playback_string (recording::string
*str
)
150 return str
->c_str ();
155 /* Get the playback::block for the given recording::block,
156 handling a NULL input with a NULL output. */
159 recording::playback_block (recording::block
*b
)
162 return b
->playback_block ();
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
)
174 m_parent_ctxt (parent_ctxt
),
176 m_first_error_str (NULL
),
177 m_owns_first_error_str (false),
178 m_last_error_str (NULL
),
179 m_owns_last_error_str (false),
184 m_builtins_manager(NULL
)
188 /* Inherit options from parent. */
190 i
< sizeof (m_str_options
) / sizeof (m_str_options
[0]);
193 const char *parent_opt
= parent_ctxt
->m_str_options
[i
];
194 m_str_options
[i
] = parent_opt
? xstrdup (parent_opt
) : NULL
;
196 memcpy (m_int_options
,
197 parent_ctxt
->m_int_options
,
198 sizeof (m_int_options
));
199 memcpy (m_bool_options
,
200 parent_ctxt
->m_bool_options
,
201 sizeof (m_bool_options
));
202 set_logger (parent_ctxt
->get_logger ());
206 memset (m_str_options
, 0, sizeof (m_str_options
));
207 memset (m_int_options
, 0, sizeof (m_int_options
));
208 memset (m_bool_options
, 0, sizeof (m_bool_options
));
211 memset (m_basic_types
, 0, sizeof (m_basic_types
));
214 /* The destructor for gcc::jit::recording::context, implicitly used by
215 gcc_jit_context_release. */
217 recording::context::~context ()
219 JIT_LOG_SCOPE (get_logger ());
222 FOR_EACH_VEC_ELT (m_mementos
, i
, m
)
227 for (i
= 0; i
< GCC_JIT_NUM_STR_OPTIONS
; ++i
)
228 free (m_str_options
[i
]);
230 if (m_builtins_manager
)
231 delete m_builtins_manager
;
233 if (m_owns_first_error_str
)
234 free (m_first_error_str
);
236 if (m_owns_last_error_str
)
237 if (m_last_error_str
!= m_first_error_str
)
238 free (m_last_error_str
);
241 /* Add the given mememto to the list of those tracked by this
242 gcc::jit::recording::context, so that e.g. it can be deleted
243 when this context is released. */
246 recording::context::record (memento
*m
)
250 m_mementos
.safe_push (m
);
253 /* Replay this context (and any parents) into the given replayer. */
256 recording::context::replay_into (replayer
*r
)
258 JIT_LOG_SCOPE (get_logger ());
262 /* If we have a parent context, we must replay it. This will
263 recursively walk backwards up the historical tree, then replay things
264 forwards "in historical order", starting with the ultimate parent
265 context, until we reach the "this" context.
267 Note that we fully replay the parent, then fully replay the child,
268 which means that inter-context references can only exist from child
269 to parent, not the other way around.
271 All of this replaying is suboptimal - it would be better to do the
272 work for the parent context *once*, rather than replaying the parent
273 every time we replay each child. However, fixing this requires deep
274 surgery to lifetime-management: we'd need every context family tree
275 to have its own GC heap, and to initialize the GCC code to use that
276 heap (with a mutex on such a heap). */
278 m_parent_ctxt
->replay_into (r
);
280 if (r
->errors_occurred ())
283 /* Replay this context's saved operations into r. */
284 FOR_EACH_VEC_ELT (m_mementos
, i
, m
)
286 /* Disabled low-level debugging, here if we need it: print what
288 Note that the calls to get_debug_string might lead to more
289 mementos being created for the strings.
290 This can also be used to exercise the debug_string
293 printf ("context %p replaying (%p): %s\n",
294 (void *)this, (void *)m
, m
->get_debug_string ());
298 if (r
->errors_occurred ())
303 /* During a playback, we associate objects from the recording with
304 their counterparts during this playback.
306 For simplicity, we store this within the recording objects.
308 The following method cleans away these associations, to ensure that
309 we never have out-of-date associations lingering on subsequent
310 playbacks (the objects pointed to are GC-managed, but the
311 recording objects don't own refs to them). */
314 recording::context::disassociate_from_playback ()
316 JIT_LOG_SCOPE (get_logger ());
321 m_parent_ctxt
->disassociate_from_playback ();
323 FOR_EACH_VEC_ELT (m_mementos
, i
, m
)
325 m
->set_playback_obj (NULL
);
329 /* Create a recording::string instance and add it to this context's list
332 This creates a fresh copy of the given 0-terminated buffer. */
335 recording::context::new_string (const char *text
)
340 recording::string
*result
= new string (this, text
);
345 /* Create a recording::location instance and add it to this context's
348 Implements the post-error-checking part of
349 gcc_jit_context_new_location. */
351 recording::location
*
352 recording::context::new_location (const char *filename
,
356 recording::location
*result
=
357 new recording::location (this,
358 new_string (filename
),
364 /* If we haven't seen this enum value yet, create a recording::type
365 instance and add it to this context's list of mementos.
367 If we have seen it before, reuse our cached value, so that repeated
368 calls on the context give the same object.
370 If we have a parent context, the cache is within the ultimate
373 Implements the post-error-checking part of
374 gcc_jit_context_get_type. */
377 recording::context::get_type (enum gcc_jit_types kind
)
379 if (!m_basic_types
[kind
])
382 m_basic_types
[kind
] = m_parent_ctxt
->get_type (kind
);
385 recording::type
*result
= new memento_of_get_type (this, kind
);
387 m_basic_types
[kind
] = result
;
391 return m_basic_types
[kind
];
394 /* Get a recording::type instance for the given size and signedness.
395 This is implemented in terms of recording::context::get_type
398 Implements the post-error-checking part of
399 gcc_jit_context_get_int_type. */
402 recording::context::get_int_type (int num_bytes
, int is_signed
)
404 /* We can't use a switch here since some of the values are macros affected
405 by options; e.g. i386.h has
406 #define LONG_TYPE_SIZE (TARGET_X32 ? 32 : BITS_PER_WORD)
407 Compare with tree.c's make_or_reuse_type. Note that the _SIZE macros
408 are in bits, rather than bytes.
410 const int num_bits
= num_bytes
* 8;
411 if (num_bits
== INT_TYPE_SIZE
)
412 return get_type (is_signed
414 : GCC_JIT_TYPE_UNSIGNED_INT
);
415 if (num_bits
== CHAR_TYPE_SIZE
)
416 return get_type (is_signed
417 ? GCC_JIT_TYPE_SIGNED_CHAR
418 : GCC_JIT_TYPE_UNSIGNED_CHAR
);
419 if (num_bits
== SHORT_TYPE_SIZE
)
420 return get_type (is_signed
422 : GCC_JIT_TYPE_UNSIGNED_SHORT
);
423 if (num_bits
== LONG_TYPE_SIZE
)
424 return get_type (is_signed
426 : GCC_JIT_TYPE_UNSIGNED_LONG
);
427 if (num_bits
== LONG_LONG_TYPE_SIZE
)
428 return get_type (is_signed
429 ? GCC_JIT_TYPE_LONG_LONG
430 : GCC_JIT_TYPE_UNSIGNED_LONG_LONG
);
432 /* Some other size, not corresponding to the C int types. */
433 /* To be written: support arbitrary other sizes, sharing by
434 memoizing at the recording::context level? */
438 /* Create a recording::type instance and add it to this context's list
441 Implements the post-error-checking part of
442 gcc_jit_context_new_array_type. */
445 recording::context::new_array_type (recording::location
*loc
,
446 recording::type
*element_type
,
449 if (struct_
*s
= element_type
->dyn_cast_struct ())
450 if (!s
->get_fields ())
453 "cannot create an array of type %s"
454 " until the fields have been set",
455 s
->get_name ()->c_str ());
458 recording::type
*result
=
459 new recording::array_type (this, loc
, element_type
, num_elements
);
464 /* Create a recording::field instance and add it to this context's list
467 Implements the post-error-checking part of
468 gcc_jit_context_new_field. */
471 recording::context::new_field (recording::location
*loc
,
472 recording::type
*type
,
475 recording::field
*result
=
476 new recording::field (this, loc
, type
, new_string (name
));
481 /* Create a recording::struct_ instance and add it to this context's
482 list of mementos and list of compound types.
484 Implements the post-error-checking part of
485 gcc_jit_context_new_struct_type. */
488 recording::context::new_struct_type (recording::location
*loc
,
491 recording::struct_
*result
= new struct_ (this, loc
, new_string (name
));
493 m_compound_types
.safe_push (result
);
497 /* Create a recording::union_ instance and add it to this context's
498 list of mementos and list of compound types.
500 Implements the first post-error-checking part of
501 gcc_jit_context_new_union_type. */
504 recording::context::new_union_type (recording::location
*loc
,
507 recording::union_
*result
= new union_ (this, loc
, new_string (name
));
509 m_compound_types
.safe_push (result
);
513 /* Create a recording::function_type instance and add it to this context's
516 Used by new_function_ptr_type and by builtins_manager::make_fn_type. */
518 recording::function_type
*
519 recording::context::new_function_type (recording::type
*return_type
,
521 recording::type
**param_types
,
524 recording::function_type
*fn_type
525 = new function_type (this,
534 /* Create a recording::type instance and add it to this context's list
537 Implements the post-error-checking part of
538 gcc_jit_context_new_function_ptr_type. */
541 recording::context::new_function_ptr_type (recording::location
*, /* unused loc */
542 recording::type
*return_type
,
544 recording::type
**param_types
,
547 recording::function_type
*fn_type
548 = new_function_type (return_type
,
553 /* Return a pointer-type to the the function type. */
554 return fn_type
->get_pointer ();
557 /* Create a recording::param instance and add it to this context's list
560 Implements the post-error-checking part of
561 gcc_jit_context_new_param. */
564 recording::context::new_param (recording::location
*loc
,
565 recording::type
*type
,
568 recording::param
*result
= new recording::param (this, loc
, type
, new_string (name
));
573 /* Create a recording::function instance and add it to this context's list
574 of mementos and list of functions.
576 Implements the post-error-checking part of
577 gcc_jit_context_new_function. */
579 recording::function
*
580 recording::context::new_function (recording::location
*loc
,
581 enum gcc_jit_function_kind kind
,
582 recording::type
*return_type
,
585 recording::param
**params
,
587 enum built_in_function builtin_id
)
589 recording::function
*result
=
590 new recording::function (this,
591 loc
, kind
, return_type
,
593 num_params
, params
, is_variadic
,
596 m_functions
.safe_push (result
);
601 /* Locate the builtins_manager (if any) for this family of contexts,
602 creating it if it doesn't exist already.
604 All of the recording contexts in a family share one builtins_manager:
605 if we have a child context, follow the parent links to get the
606 ultimate ancestor context, and look for it/store it there. */
609 recording::context::get_builtins_manager ()
612 return m_parent_ctxt
->get_builtins_manager ();
614 if (!m_builtins_manager
)
615 m_builtins_manager
= new builtins_manager (this);
617 return m_builtins_manager
;
620 /* Get a recording::function instance, which is lazily-created and added
621 to the context's lists of mementos.
623 Implements the post-error-checking part of
624 gcc_jit_context_get_builtin_function. */
626 recording::function
*
627 recording::context::get_builtin_function (const char *name
)
629 builtins_manager
*bm
= get_builtins_manager ();
630 return bm
->get_builtin_function (name
);
633 /* Create a recording::global instance and add it to this context's list
636 Implements the post-error-checking part of
637 gcc_jit_context_new_global. */
640 recording::context::new_global (recording::location
*loc
,
641 recording::type
*type
,
644 recording::lvalue
*result
=
645 new recording::global (this, loc
, type
, new_string (name
));
650 /* Create a recording::memento_of_new_rvalue_from_int instance and add
651 it to this context's list of mementos.
653 Implements the post-error-checking part of
654 gcc_jit_context_new_rvalue_from_int. */
657 recording::context::new_rvalue_from_int (recording::type
*type
,
660 recording::rvalue
*result
=
661 new memento_of_new_rvalue_from_int (this, NULL
, type
, value
);
666 /* Create a recording::memento_of_new_rvalue_from_double instance and
667 add it to this context's list of mementos.
669 Implements the post-error-checking part of
670 gcc_jit_context_new_rvalue_from_double. */
673 recording::context::new_rvalue_from_double (recording::type
*type
,
676 recording::rvalue
*result
=
677 new memento_of_new_rvalue_from_double (this, NULL
, type
, value
);
682 /* Create a recording::memento_of_new_rvalue_from_ptr instance and add
683 it to this context's list of mementos.
685 Implements the post-error-checking part of
686 gcc_jit_context_new_rvalue_from_ptr. */
689 recording::context::new_rvalue_from_ptr (recording::type
*type
,
692 recording::rvalue
*result
=
693 new memento_of_new_rvalue_from_ptr (this, NULL
, type
, value
);
698 /* Create a recording::memento_of_new_string_literal instance and add it
699 to this context's list of mementos.
701 Implements the post-error-checking part of
702 gcc_jit_context_new_string_literal. */
705 recording::context::new_string_literal (const char *value
)
707 recording::rvalue
*result
=
708 new memento_of_new_string_literal (this, NULL
, new_string (value
));
713 /* Create a recording::unary_op instance and add it to this context's
716 Implements the post-error-checking part of
717 gcc_jit_context_new_unary_op. */
720 recording::context::new_unary_op (recording::location
*loc
,
721 enum gcc_jit_unary_op op
,
722 recording::type
*result_type
,
723 recording::rvalue
*a
)
725 recording::rvalue
*result
=
726 new unary_op (this, loc
, op
, result_type
, a
);
731 /* Create a recording::binary_op instance and add it to this context's
734 Implements the post-error-checking part of
735 gcc_jit_context_new_binary_op. */
738 recording::context::new_binary_op (recording::location
*loc
,
739 enum gcc_jit_binary_op op
,
740 recording::type
*result_type
,
741 recording::rvalue
*a
,
742 recording::rvalue
*b
)
744 recording::rvalue
*result
=
745 new binary_op (this, loc
, op
, result_type
, a
, b
);
750 /* Create a recording::comparison instance and add it to this context's
753 Implements the post-error-checking part of
754 gcc_jit_context_new_comparison. */
757 recording::context::new_comparison (recording::location
*loc
,
758 enum gcc_jit_comparison op
,
759 recording::rvalue
*a
,
760 recording::rvalue
*b
)
762 recording::rvalue
*result
= new comparison (this, loc
, op
, a
, b
);
767 /* Create a recording::cast instance and add it to this context's list
770 Implements the post-error-checking part of
771 gcc_jit_context_new_cast. */
774 recording::context::new_cast (recording::location
*loc
,
775 recording::rvalue
*expr
,
776 recording::type
*type_
)
778 recording::rvalue
*result
= new cast (this, loc
, expr
, type_
);
783 /* Create a recording::call instance and add it to this context's list
786 Implements the post-error-checking part of
787 gcc_jit_context_new_call. */
790 recording::context::new_call (recording::location
*loc
,
792 int numargs
, recording::rvalue
**args
)
794 recording::rvalue
*result
= new call (this, loc
, func
, numargs
, args
);
799 /* Create a recording::call_through_ptr instance and add it to this
800 context's list of mementos.
802 Implements the post-error-checking part of
803 gcc_jit_context_new_call_through_ptr. */
806 recording::context::new_call_through_ptr (recording::location
*loc
,
807 recording::rvalue
*fn_ptr
,
809 recording::rvalue
**args
)
811 recording::rvalue
*result
= new call_through_ptr (this, loc
, fn_ptr
, numargs
, args
);
816 /* Create a recording::array_access instance and add it to this context's list
819 Implements the post-error-checking part of
820 gcc_jit_context_new_array_access. */
823 recording::context::new_array_access (recording::location
*loc
,
824 recording::rvalue
*ptr
,
825 recording::rvalue
*index
)
827 recording::lvalue
*result
= new array_access (this, loc
, ptr
, index
);
832 /* Set the given string option for this context, or add an error if
835 Implements the post-error-checking part of
836 gcc_jit_context_set_str_option. */
839 recording::context::set_str_option (enum gcc_jit_str_option opt
,
842 if (opt
< 0 || opt
>= GCC_JIT_NUM_STR_OPTIONS
)
845 "unrecognized (enum gcc_jit_str_option) value: %i", opt
);
848 free (m_str_options
[opt
]);
849 m_str_options
[opt
] = value
? xstrdup (value
) : NULL
;
852 /* Set the given integer option for this context, or add an error if
855 Implements the post-error-checking part of
856 gcc_jit_context_set_int_option. */
859 recording::context::set_int_option (enum gcc_jit_int_option opt
,
862 if (opt
< 0 || opt
>= GCC_JIT_NUM_INT_OPTIONS
)
865 "unrecognized (enum gcc_jit_int_option) value: %i", opt
);
868 m_int_options
[opt
] = value
;
871 /* Set the given boolean option for this context, or add an error if
874 Implements the post-error-checking part of
875 gcc_jit_context_set_bool_option. */
878 recording::context::set_bool_option (enum gcc_jit_bool_option opt
,
881 if (opt
< 0 || opt
>= GCC_JIT_NUM_BOOL_OPTIONS
)
884 "unrecognized (enum gcc_jit_bool_option) value: %i", opt
);
887 m_bool_options
[opt
] = value
? true : false;
890 /* Add the given dumpname/out_ptr pair to this context's list of requested
893 Implements the post-error-checking part of
894 gcc_jit_context_enable_dump. */
897 recording::context::enable_dump (const char *dumpname
,
901 gcc_assert (dumpname
);
902 gcc_assert (out_ptr
);
904 d
.m_dumpname
= dumpname
;
905 d
.m_out_ptr
= out_ptr
;
907 m_requested_dumps
.safe_push (d
);
910 /* Validate this context, and if it passes, compile it within a
913 Implements the post-error-checking part of
914 gcc_jit_context_compile. */
917 recording::context::compile ()
919 JIT_LOG_SCOPE (get_logger ());
923 if (errors_occurred ())
926 /* Set up a playback context. */
927 ::gcc::jit::playback::context
replayer (this);
930 result
*result_obj
= replayer
.compile ();
935 /* Format the given error using printf's conventions, print
936 it to stderr, and add it to the context. */
939 recording::context::add_error (location
*loc
, const char *fmt
, ...)
943 add_error_va (loc
, fmt
, ap
);
947 /* Format the given error using printf's conventions, print
948 it to stderr, and add it to the context. */
951 recording::context::add_error_va (location
*loc
, const char *fmt
, va_list ap
)
957 JIT_LOG_SCOPE (get_logger ());
959 vasprintf (&malloced_msg
, fmt
, ap
);
962 errmsg
= malloced_msg
;
963 has_ownership
= true;
967 errmsg
= "out of memory generating error message";
968 has_ownership
= false;
971 get_logger ()->log ("error %i: %s", m_error_count
, errmsg
);
973 const char *ctxt_progname
=
974 get_str_option (GCC_JIT_STR_OPTION_PROGNAME
);
976 ctxt_progname
= "libgccjit.so";
979 fprintf (stderr
, "%s: %s: error: %s\n",
981 loc
->get_debug_string (),
984 fprintf (stderr
, "%s: error: %s\n",
990 m_first_error_str
= const_cast <char *> (errmsg
);
991 m_owns_first_error_str
= has_ownership
;
994 if (m_owns_last_error_str
)
995 if (m_last_error_str
!= m_first_error_str
)
996 free (m_last_error_str
);
997 m_last_error_str
= const_cast <char *> (errmsg
);
998 m_owns_last_error_str
= has_ownership
;
1003 /* Get the message for the first error that occurred on this context, or
1004 NULL if no errors have occurred on it.
1006 Implements the post-error-checking part of
1007 gcc_jit_context_get_first_error. */
1010 recording::context::get_first_error () const
1012 return m_first_error_str
;
1015 /* Get the message for the last error that occurred on this context, or
1016 NULL if no errors have occurred on it.
1018 Implements the post-error-checking part of
1019 gcc_jit_context_get_last_error. */
1022 recording::context::get_last_error () const
1024 return m_last_error_str
;
1027 /* Lazily generate and record a recording::type representing an opaque
1028 struct named "FILE".
1030 For use if client code tries to dereference the result of
1031 get_type (GCC_JIT_TYPE_FILE_PTR). */
1034 recording::context::get_opaque_FILE_type ()
1037 m_FILE_type
= new_struct_type (NULL
, "FILE");
1041 /* Dump a C-like representation of the given context to the given path.
1042 If UPDATE_LOCATIONS is true, update the locations within the
1043 context's mementos to point to the dumpfile.
1045 Implements the post-error-checking part of
1046 gcc_jit_context_dump_to_file. */
1049 recording::context::dump_to_file (const char *path
, bool update_locations
)
1052 dump
d (*this, path
, update_locations
);
1054 /* Forward declaration of structs and unions. */
1056 FOR_EACH_VEC_ELT (m_compound_types
, i
, st
)
1058 d
.write ("%s;\n\n", st
->get_debug_string ());
1061 /* Content of structs, where set. */
1062 FOR_EACH_VEC_ELT (m_compound_types
, i
, st
)
1063 if (st
->get_fields ())
1065 st
->get_fields ()->write_to_dump (d
);
1070 FOR_EACH_VEC_ELT (m_functions
, i
, fn
)
1072 fn
->write_to_dump (d
);
1076 /* Copy the requested dumps within this context and all ancestors into
1080 recording::context::get_all_requested_dumps (vec
<recording::requested_dump
> *out
)
1083 m_parent_ctxt
->get_all_requested_dumps (out
);
1085 out
->reserve (m_requested_dumps
.length ());
1086 out
->splice (m_requested_dumps
);
1089 /* This is a pre-compilation check for the context (and any parents).
1091 Detect errors within the context, adding errors if any are found. */
1094 recording::context::validate ()
1096 JIT_LOG_SCOPE (get_logger ());
1099 m_parent_ctxt
->validate ();
1103 FOR_EACH_VEC_ELT (m_functions
, i
, fn
)
1107 /* The implementation of class gcc::jit::recording::memento. */
1109 /* Get a (const char *) debug description of the given memento, by
1110 calling the pure-virtual make_debug_string hook, caching the
1113 It is intended that this should only be called in debugging and
1114 error-handling paths, so this doesn't need to be particularly
1118 recording::memento::get_debug_string ()
1120 if (!m_debug_string
)
1121 m_debug_string
= make_debug_string ();
1122 return m_debug_string
->c_str ();
1125 /* Default implementation of recording::memento::write_to_dump, writing
1126 an indented form of the memento's debug string to the dump. */
1129 recording::memento::write_to_dump (dump
&d
)
1131 d
.write(" %s\n", get_debug_string ());
1134 /* The implementation of class gcc::jit::recording::string. */
1136 /* Constructor for gcc::jit::recording::string::string, allocating a
1137 copy of the given text using new char[]. */
1139 recording::string::string (context
*ctxt
, const char *text
)
1142 m_len
= strlen (text
);
1143 m_buffer
= new char[m_len
+ 1];
1144 strcpy (m_buffer
, text
);
1147 /* Destructor for gcc::jit::recording::string::string. */
1149 recording::string::~string ()
1154 /* Function for making gcc::jit::recording::string instances on a
1155 context via printf-style formatting.
1157 It is intended that this should only be called in debugging and
1158 error-handling paths, so this doesn't need to be particularly
1159 optimized, hence the double-copy of the string is acceptable. */
1162 recording::string::from_printf (context
*ctxt
, const char *fmt
, ...)
1166 recording::string
*result
;
1169 vasprintf (&buf
, fmt
, ap
);
1174 ctxt
->add_error (NULL
, "malloc failure");
1178 result
= ctxt
->new_string (buf
);
1183 /* Implementation of recording::memento::make_debug_string for strings,
1184 wrapping the given string in quotes and escaping as necessary. */
1187 recording::string::make_debug_string ()
1189 /* Hack to avoid infinite recursion into strings when logging all
1190 mementos: don't re-escape strings: */
1191 if (m_buffer
[0] == '"')
1194 /* Wrap in quotes and do escaping etc */
1196 size_t sz
= (1 /* opening quote */
1197 + (m_len
* 2) /* each char might get escaped */
1198 + 1 /* closing quote */
1199 + 1); /* nil termintator */
1200 char *tmp
= new char[sz
];
1203 #define APPEND(CH) do { gcc_assert (len < sz); tmp[len++] = (CH); } while (0)
1204 APPEND('"'); /* opening quote */
1205 for (size_t i
= 0; i
< m_len
; i
++)
1207 char ch
= m_buffer
[i
];
1208 if (ch
== '\t' || ch
== '\n' || ch
== '\\' || ch
== '"')
1212 APPEND('"'); /* closing quote */
1214 tmp
[len
] = '\0'; /* nil termintator */
1216 string
*result
= m_ctxt
->new_string (tmp
);
1222 /* The implementation of class gcc::jit::recording::location. */
1224 /* Implementation of recording::memento::replay_into for locations.
1226 Create a new playback::location and store it into the
1227 recording::location's m_playback_obj field. */
1230 recording::location::replay_into (replayer
*r
)
1232 m_playback_obj
= r
->new_location (this,
1233 m_filename
->c_str (),
1238 /* Implementation of recording::memento::make_debug_string for locations,
1239 turning them into the usual form:
1240 FILENAME:LINE:COLUMN
1241 like we do when emitting diagnostics. */
1244 recording::location::make_debug_string ()
1246 return string::from_printf (m_ctxt
,
1248 m_filename
->c_str (), m_line
, m_column
);
1251 /* The implementation of class gcc::jit::recording::type. */
1253 /* Given a type T, get the type T*.
1255 If this doesn't already exist, generate a new memento_of_get_pointer
1256 instance and add it to this type's context's list of mementos.
1258 Otherwise, use the cached type.
1260 Implements the post-error-checking part of
1261 gcc_jit_type_get_pointer. */
1264 recording::type::get_pointer ()
1266 if (!m_pointer_to_this_type
)
1268 m_pointer_to_this_type
= new memento_of_get_pointer (this);
1269 m_ctxt
->record (m_pointer_to_this_type
);
1271 return m_pointer_to_this_type
;
1274 /* Given a type T, get the type const T.
1276 Implements the post-error-checking part of
1277 gcc_jit_type_get_const. */
1280 recording::type::get_const ()
1282 recording::type
*result
= new memento_of_get_const (this);
1283 m_ctxt
->record (result
);
1287 /* Given a type T, get the type volatile T.
1289 Implements the post-error-checking part of
1290 gcc_jit_type_get_volatile. */
1293 recording::type::get_volatile ()
1295 recording::type
*result
= new memento_of_get_volatile (this);
1296 m_ctxt
->record (result
);
1300 /* Implementation of pure virtual hook recording::type::dereference for
1301 recording::memento_of_get_type. */
1304 recording::memento_of_get_type::dereference ()
1308 default: gcc_unreachable ();
1310 case GCC_JIT_TYPE_VOID
:
1313 case GCC_JIT_TYPE_VOID_PTR
:
1314 return m_ctxt
->get_type (GCC_JIT_TYPE_VOID
);
1316 case GCC_JIT_TYPE_BOOL
:
1317 case GCC_JIT_TYPE_CHAR
:
1318 case GCC_JIT_TYPE_SIGNED_CHAR
:
1319 case GCC_JIT_TYPE_UNSIGNED_CHAR
:
1320 case GCC_JIT_TYPE_SHORT
:
1321 case GCC_JIT_TYPE_UNSIGNED_SHORT
:
1322 case GCC_JIT_TYPE_INT
:
1323 case GCC_JIT_TYPE_UNSIGNED_INT
:
1324 case GCC_JIT_TYPE_LONG
:
1325 case GCC_JIT_TYPE_UNSIGNED_LONG
:
1326 case GCC_JIT_TYPE_LONG_LONG
:
1327 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG
:
1328 case GCC_JIT_TYPE_FLOAT
:
1329 case GCC_JIT_TYPE_DOUBLE
:
1330 case GCC_JIT_TYPE_LONG_DOUBLE
:
1331 case GCC_JIT_TYPE_COMPLEX_FLOAT
:
1332 case GCC_JIT_TYPE_COMPLEX_DOUBLE
:
1333 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE
:
1334 /* Not a pointer: */
1337 case GCC_JIT_TYPE_CONST_CHAR_PTR
:
1338 return m_ctxt
->get_type (GCC_JIT_TYPE_CHAR
)->get_const ();
1340 case GCC_JIT_TYPE_SIZE_T
:
1341 /* Not a pointer: */
1344 case GCC_JIT_TYPE_FILE_PTR
:
1345 /* Give the client code back an opaque "struct FILE". */
1346 return m_ctxt
->get_opaque_FILE_type ();
1350 /* Implementation of pure virtual hook recording::type::is_int for
1351 recording::memento_of_get_type. */
1354 recording::memento_of_get_type::is_int () const
1358 default: gcc_unreachable ();
1360 case GCC_JIT_TYPE_VOID
:
1363 case GCC_JIT_TYPE_VOID_PTR
:
1366 case GCC_JIT_TYPE_BOOL
:
1369 case GCC_JIT_TYPE_CHAR
:
1370 case GCC_JIT_TYPE_SIGNED_CHAR
:
1371 case GCC_JIT_TYPE_UNSIGNED_CHAR
:
1372 case GCC_JIT_TYPE_SHORT
:
1373 case GCC_JIT_TYPE_UNSIGNED_SHORT
:
1374 case GCC_JIT_TYPE_INT
:
1375 case GCC_JIT_TYPE_UNSIGNED_INT
:
1376 case GCC_JIT_TYPE_LONG
:
1377 case GCC_JIT_TYPE_UNSIGNED_LONG
:
1378 case GCC_JIT_TYPE_LONG_LONG
:
1379 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG
:
1382 case GCC_JIT_TYPE_FLOAT
:
1383 case GCC_JIT_TYPE_DOUBLE
:
1384 case GCC_JIT_TYPE_LONG_DOUBLE
:
1387 case GCC_JIT_TYPE_CONST_CHAR_PTR
:
1390 case GCC_JIT_TYPE_SIZE_T
:
1393 case GCC_JIT_TYPE_FILE_PTR
:
1396 case GCC_JIT_TYPE_COMPLEX_FLOAT
:
1397 case GCC_JIT_TYPE_COMPLEX_DOUBLE
:
1398 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE
:
1403 /* Implementation of pure virtual hook recording::type::is_float for
1404 recording::memento_of_get_type. */
1407 recording::memento_of_get_type::is_float () const
1411 default: gcc_unreachable ();
1413 case GCC_JIT_TYPE_VOID
:
1416 case GCC_JIT_TYPE_VOID_PTR
:
1419 case GCC_JIT_TYPE_BOOL
:
1422 case GCC_JIT_TYPE_CHAR
:
1423 case GCC_JIT_TYPE_SIGNED_CHAR
:
1424 case GCC_JIT_TYPE_UNSIGNED_CHAR
:
1425 case GCC_JIT_TYPE_SHORT
:
1426 case GCC_JIT_TYPE_UNSIGNED_SHORT
:
1427 case GCC_JIT_TYPE_INT
:
1428 case GCC_JIT_TYPE_UNSIGNED_INT
:
1429 case GCC_JIT_TYPE_LONG
:
1430 case GCC_JIT_TYPE_UNSIGNED_LONG
:
1431 case GCC_JIT_TYPE_LONG_LONG
:
1432 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG
:
1435 case GCC_JIT_TYPE_FLOAT
:
1436 case GCC_JIT_TYPE_DOUBLE
:
1437 case GCC_JIT_TYPE_LONG_DOUBLE
:
1440 case GCC_JIT_TYPE_CONST_CHAR_PTR
:
1443 case GCC_JIT_TYPE_SIZE_T
:
1446 case GCC_JIT_TYPE_FILE_PTR
:
1449 case GCC_JIT_TYPE_COMPLEX_FLOAT
:
1450 case GCC_JIT_TYPE_COMPLEX_DOUBLE
:
1451 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE
:
1456 /* Implementation of pure virtual hook recording::type::is_bool for
1457 recording::memento_of_get_type. */
1460 recording::memento_of_get_type::is_bool () const
1464 default: gcc_unreachable ();
1466 case GCC_JIT_TYPE_VOID
:
1469 case GCC_JIT_TYPE_VOID_PTR
:
1472 case GCC_JIT_TYPE_BOOL
:
1475 case GCC_JIT_TYPE_CHAR
:
1476 case GCC_JIT_TYPE_SIGNED_CHAR
:
1477 case GCC_JIT_TYPE_UNSIGNED_CHAR
:
1478 case GCC_JIT_TYPE_SHORT
:
1479 case GCC_JIT_TYPE_UNSIGNED_SHORT
:
1480 case GCC_JIT_TYPE_INT
:
1481 case GCC_JIT_TYPE_UNSIGNED_INT
:
1482 case GCC_JIT_TYPE_LONG
:
1483 case GCC_JIT_TYPE_UNSIGNED_LONG
:
1484 case GCC_JIT_TYPE_LONG_LONG
:
1485 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG
:
1488 case GCC_JIT_TYPE_FLOAT
:
1489 case GCC_JIT_TYPE_DOUBLE
:
1490 case GCC_JIT_TYPE_LONG_DOUBLE
:
1493 case GCC_JIT_TYPE_CONST_CHAR_PTR
:
1496 case GCC_JIT_TYPE_SIZE_T
:
1499 case GCC_JIT_TYPE_FILE_PTR
:
1502 case GCC_JIT_TYPE_COMPLEX_FLOAT
:
1503 case GCC_JIT_TYPE_COMPLEX_DOUBLE
:
1504 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE
:
1509 /* Implementation of pure virtual hook recording::memento::replay_into
1510 for recording::memento_of_get_type. */
1513 recording::memento_of_get_type::replay_into (replayer
*r
)
1515 set_playback_obj (r
->get_type (m_kind
));
1518 /* The implementation of class gcc::jit::recording::memento_of_get_type. */
1520 /* Descriptive strings for each of enum gcc_jit_types. */
1522 static const char * const get_type_strings
[] = {
1523 "void", /* GCC_JIT_TYPE_VOID */
1524 "void *", /* GCC_JIT_TYPE_VOID_PTR */
1526 "bool", /* GCC_JIT_TYPE_BOOL */
1528 "char", /* GCC_JIT_TYPE_CHAR */
1529 "signed char", /* GCC_JIT_TYPE_SIGNED_CHAR */
1530 "unsigned char", /* GCC_JIT_TYPE_UNSIGNED_CHAR */
1532 "short", /* GCC_JIT_TYPE_SHORT */
1533 "unsigned short", /* GCC_JIT_TYPE_UNSIGNED_SHORT */
1535 "int", /* GCC_JIT_TYPE_INT */
1536 "unsigned int", /* GCC_JIT_TYPE_UNSIGNED_INT */
1538 "long", /* GCC_JIT_TYPE_LONG */
1539 "unsigned long", /* GCC_JIT_TYPE_UNSIGNED_LONG, */
1541 "long long", /* GCC_JIT_TYPE_LONG_LONG */
1542 "unsigned long long", /* GCC_JIT_TYPE_UNSIGNED_LONG_LONG */
1544 "float", /* GCC_JIT_TYPE_FLOAT */
1545 "double", /* GCC_JIT_TYPE_DOUBLE */
1546 "long double", /* GCC_JIT_TYPE_LONG_DOUBLE */
1548 "const char *", /* GCC_JIT_TYPE_CONST_CHAR_PTR */
1550 "size_t", /* GCC_JIT_TYPE_SIZE_T */
1552 "FILE *", /* GCC_JIT_TYPE_FILE_PTR */
1554 "complex float", /* GCC_JIT_TYPE_COMPLEX_FLOAT */
1555 "complex double", /* GCC_JIT_TYPE_COMPLEX_DOUBLE */
1556 "complex long double" /* GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE */
1560 /* Implementation of recording::memento::make_debug_string for
1561 results of get_type, using a simple table of type names. */
1564 recording::memento_of_get_type::make_debug_string ()
1566 return m_ctxt
->new_string (get_type_strings
[m_kind
]);
1569 /* The implementation of class gcc::jit::recording::memento_of_get_pointer. */
1571 /* Override of default implementation of
1572 recording::type::accepts_writes_from for get_pointer.
1574 Require a pointer type, and allowing writes to
1575 (const T *) from a (T*), but not the other way around. */
1578 recording::memento_of_get_pointer::accepts_writes_from (type
*rtype
)
1580 /* Must be a pointer type: */
1581 type
*rtype_points_to
= rtype
->is_pointer ();
1582 if (!rtype_points_to
)
1585 /* It's OK to assign to a (const T *) from a (T *). */
1586 return m_other_type
->unqualified ()
1587 ->accepts_writes_from (rtype_points_to
);
1590 /* Implementation of pure virtual hook recording::memento::replay_into
1591 for recording::memento_of_get_pointer. */
1594 recording::memento_of_get_pointer::replay_into (replayer
*)
1596 set_playback_obj (m_other_type
->playback_type ()->get_pointer ());
1599 /* Implementation of recording::memento::make_debug_string for
1600 results of get_pointer, adding " *" to the underlying type,
1601 with special-casing to handle function pointer types. */
1604 recording::memento_of_get_pointer::make_debug_string ()
1606 /* Special-case function pointer types, to put the "*" in parens between
1607 the return type and the params (for one level of dereferencing, at
1609 if (function_type
*fn_type
= m_other_type
->dyn_cast_function_type ())
1610 return fn_type
->make_debug_string_with_ptr ();
1612 return string::from_printf (m_ctxt
,
1613 "%s *", m_other_type
->get_debug_string ());
1616 /* The implementation of class gcc::jit::recording::memento_of_get_const. */
1618 /* Implementation of pure virtual hook recording::memento::replay_into
1619 for recording::memento_of_get_const. */
1622 recording::memento_of_get_const::replay_into (replayer
*)
1624 set_playback_obj (m_other_type
->playback_type ()->get_const ());
1627 /* Implementation of recording::memento::make_debug_string for
1628 results of get_const, prepending "const ". */
1631 recording::memento_of_get_const::make_debug_string ()
1633 return string::from_printf (m_ctxt
,
1634 "const %s", m_other_type
->get_debug_string ());
1637 /* The implementation of class gcc::jit::recording::memento_of_get_volatile. */
1639 /* Implementation of pure virtual hook recording::memento::replay_into
1640 for recording::memento_of_get_volatile. */
1643 recording::memento_of_get_volatile::replay_into (replayer
*)
1645 set_playback_obj (m_other_type
->playback_type ()->get_volatile ());
1648 /* Implementation of recording::memento::make_debug_string for
1649 results of get_volatile, prepending "volatile ". */
1652 recording::memento_of_get_volatile::make_debug_string ()
1654 return string::from_printf (m_ctxt
,
1655 "volatile %s", m_other_type
->get_debug_string ());
1658 /* The implementation of class gcc::jit::recording::array_type */
1660 /* Implementation of pure virtual hook recording::type::dereference for
1661 recording::array_type. */
1664 recording::array_type::dereference ()
1666 return m_element_type
;
1669 /* Implementation of pure virtual hook recording::memento::replay_into
1670 for recording::array_type. */
1673 recording::array_type::replay_into (replayer
*r
)
1675 set_playback_obj (r
->new_array_type (playback_location (r
, m_loc
),
1676 m_element_type
->playback_type (),
1680 /* Implementation of recording::memento::make_debug_string for
1681 results of new_array_type. */
1684 recording::array_type::make_debug_string ()
1686 return string::from_printf (m_ctxt
,
1688 m_element_type
->get_debug_string (),
1692 /* The implementation of class gcc::jit::recording::function_type */
1694 /* Constructor for gcc::jit::recording::function_type. */
1696 recording::function_type::function_type (context
*ctxt
,
1702 m_return_type (return_type
),
1704 m_is_variadic (is_variadic
)
1706 for (int i
= 0; i
< num_params
; i
++)
1707 m_param_types
.safe_push (param_types
[i
]);
1710 /* Implementation of pure virtual hook recording::type::dereference for
1711 recording::function_type. */
1714 recording::function_type::dereference ()
1719 /* Implementation of pure virtual hook recording::memento::replay_into
1720 for recording::function_type. */
1723 recording::function_type::replay_into (replayer
*r
)
1725 /* Convert m_param_types to a vec of playback type. */
1726 auto_vec
<playback::type
*> param_types
;
1728 recording::type
*type
;
1729 param_types
.create (m_param_types
.length ());
1730 FOR_EACH_VEC_ELT (m_param_types
, i
, type
)
1731 param_types
.safe_push (type
->playback_type ());
1733 set_playback_obj (r
->new_function_type (m_return_type
->playback_type (),
1738 /* Special-casing for make_debug_string for get_pointer results for
1739 handling (one level) of pointers to functions. */
1742 recording::function_type::make_debug_string_with_ptr ()
1744 return make_debug_string_with ("(*) ");
1747 /* Implementation of recording::memento::make_debug_string for
1748 results of new_function_type. */
1751 recording::function_type::make_debug_string ()
1753 return make_debug_string_with ("");
1756 /* Build a debug string representation of the form:
1758 RESULT_TYPE INSERT (PARAM_TYPES)
1760 for use when handling 0 and 1 level of indirection to this
1764 recording::function_type::make_debug_string_with (const char *insert
)
1766 /* First, build a buffer for the arguments. */
1767 /* Calculate length of said buffer. */
1768 size_t sz
= 1; /* nil terminator */
1769 for (unsigned i
= 0; i
< m_param_types
.length (); i
++)
1771 sz
+= strlen (m_param_types
[i
]->get_debug_string ());
1772 sz
+= 2; /* ", " separator */
1775 sz
+= 5; /* ", ..." separator and ellipsis */
1777 /* Now allocate and populate the buffer. */
1778 char *argbuf
= new char[sz
];
1781 for (unsigned i
= 0; i
< m_param_types
.length (); i
++)
1783 strcpy (argbuf
+ len
, m_param_types
[i
]->get_debug_string ());
1784 len
+= strlen (m_param_types
[i
]->get_debug_string ());
1785 if (i
+ 1 < m_param_types
.length ())
1787 strcpy (argbuf
+ len
, ", ");
1793 if (m_param_types
.length ())
1795 strcpy (argbuf
+ len
, ", ");
1798 strcpy (argbuf
+ len
, "...");
1803 /* ...and use it to get the string for the call as a whole. */
1804 string
*result
= string::from_printf (m_ctxt
,
1806 m_return_type
->get_debug_string (),
1815 /* The implementation of class gcc::jit::recording::field. */
1817 /* Implementation of pure virtual hook recording::memento::replay_into
1818 for recording::field. */
1821 recording::field::replay_into (replayer
*r
)
1823 set_playback_obj (r
->new_field (playback_location (r
, m_loc
),
1824 m_type
->playback_type (),
1825 playback_string (m_name
)));
1828 /* Override the default implementation of
1829 recording::memento::write_to_dump. Dump each field
1830 by dumping a line of the form:
1832 so that we can build up a struct/union field-byfield. */
1835 recording::field::write_to_dump (dump
&d
)
1837 d
.write (" %s %s;\n",
1838 m_type
->get_debug_string (),
1842 /* Implementation of recording::memento::make_debug_string for
1843 results of new_field. */
1846 recording::field::make_debug_string ()
1851 /* The implementation of class gcc::jit::recording::compound_type */
1853 /* The constructor for gcc::jit::recording::compound_type. */
1855 recording::compound_type::compound_type (context
*ctxt
,
1865 /* Set the fields of a compound type.
1867 Implements the post-error-checking part of
1868 gcc_jit_struct_set_fields, and is also used by
1869 gcc_jit_context_new_union_type. */
1872 recording::compound_type::set_fields (location
*loc
,
1874 field
**field_array
)
1877 gcc_assert (NULL
== m_fields
);
1879 m_fields
= new fields (this, num_fields
, field_array
);
1880 m_ctxt
->record (m_fields
);
1883 /* Implementation of pure virtual hook recording::type::dereference for
1884 recording::compound_type. */
1887 recording::compound_type::dereference ()
1889 return NULL
; /* not a pointer */
1892 /* The implementation of class gcc::jit::recording::struct_. */
1894 /* The constructor for gcc::jit::recording::struct_. */
1896 recording::struct_::struct_ (context
*ctxt
,
1899 : compound_type (ctxt
, loc
, name
)
1903 /* Implementation of pure virtual hook recording::memento::replay_into
1904 for recording::struct_. */
1907 recording::struct_::replay_into (replayer
*r
)
1910 r
->new_compound_type (playback_location (r
, get_loc ()),
1911 get_name ()->c_str (),
1912 true /* is_struct */));
1915 /* Implementation of recording::memento::make_debug_string for
1919 recording::struct_::make_debug_string ()
1921 return string::from_printf (m_ctxt
,
1922 "struct %s", get_name ()->c_str ());
1925 /* The implementation of class gcc::jit::recording::union_. */
1927 /* The constructor for gcc::jit::recording::union_. */
1929 recording::union_::union_ (context
*ctxt
,
1932 : compound_type (ctxt
, loc
, name
)
1936 /* Implementation of pure virtual hook recording::memento::replay_into
1937 for recording::union_. */
1940 recording::union_::replay_into (replayer
*r
)
1943 r
->new_compound_type (playback_location (r
, get_loc ()),
1944 get_name ()->c_str (),
1945 false /* is_struct */));
1948 /* Implementation of recording::memento::make_debug_string for
1952 recording::union_::make_debug_string ()
1954 return string::from_printf (m_ctxt
,
1955 "union %s", get_name ()->c_str ());
1958 /* The implementation of class gcc::jit::recording::fields. */
1960 /* The constructor for gcc::jit::recording::fields. */
1962 recording::fields::fields (compound_type
*struct_or_union
,
1965 : memento (struct_or_union
->m_ctxt
),
1966 m_struct_or_union (struct_or_union
),
1969 for (int i
= 0; i
< num_fields
; i
++)
1971 gcc_assert (fields
[i
]->get_container () == NULL
);
1972 fields
[i
]->set_container (m_struct_or_union
);
1973 m_fields
.safe_push (fields
[i
]);
1977 /* Implementation of pure virtual hook recording::memento::replay_into
1978 for recording::fields. */
1981 recording::fields::replay_into (replayer
*)
1983 auto_vec
<playback::field
*> playback_fields
;
1984 playback_fields
.create (m_fields
.length ());
1985 for (unsigned i
= 0; i
< m_fields
.length (); i
++)
1986 playback_fields
.safe_push (m_fields
[i
]->playback_field ());
1987 m_struct_or_union
->playback_compound_type ()->set_fields (&playback_fields
);
1990 /* Override the default implementation of
1991 recording::memento::write_to_dump by writing a union/struct
1992 declaration of this form:
2004 recording::fields::write_to_dump (dump
&d
)
2009 d
.write ("%s\n{\n", m_struct_or_union
->get_debug_string ());
2010 FOR_EACH_VEC_ELT (m_fields
, i
, f
)
2011 f
->write_to_dump (d
);
2015 /* Implementation of recording::memento::make_debug_string for
2019 recording::fields::make_debug_string ()
2021 return string::from_printf (m_ctxt
,
2025 /* The implementation of class gcc::jit::recording::rvalue. */
2027 /* Create a recording::access_field_rvalue instance and add it to
2028 the rvalue's context's list of mementos.
2030 Implements the post-error-checking part of
2031 gcc_jit_rvalue_access_field. */
2034 recording::rvalue::access_field (recording::location
*loc
,
2037 recording::rvalue
*result
=
2038 new access_field_rvalue (m_ctxt
, loc
, this, field
);
2039 m_ctxt
->record (result
);
2043 /* Create a recording::dereference_field_rvalue instance and add it to
2044 the rvalue's context's list of mementos.
2046 Implements the post-error-checking part of
2047 gcc_jit_rvalue_dereference_field. */
2050 recording::rvalue::dereference_field (recording::location
*loc
,
2053 recording::lvalue
*result
=
2054 new dereference_field_rvalue (m_ctxt
, loc
, this, field
);
2055 m_ctxt
->record (result
);
2059 /* Create a recording::dereference_rvalue instance and add it to the
2060 rvalue's context's list of mementos.
2062 Implements the post-error-checking part of
2063 gcc_jit_rvalue_dereference. */
2066 recording::rvalue::dereference (recording::location
*loc
)
2068 recording::lvalue
*result
=
2069 new dereference_rvalue (m_ctxt
, loc
, this);
2070 m_ctxt
->record (result
);
2074 /* The implementation of class gcc::jit::recording::lvalue. */
2076 /* Create a recording::new_access_field_of_lvalue instance and add it to
2077 the lvalue's context's list of mementos.
2079 Implements the post-error-checking part of
2080 gcc_jit_lvalue_access_field. */
2083 recording::lvalue::access_field (recording::location
*loc
,
2086 recording::lvalue
*result
=
2087 new access_field_of_lvalue (m_ctxt
, loc
, this, field
);
2088 m_ctxt
->record (result
);
2092 /* Create a recording::get_address_of_lvalue instance and add it to
2093 the lvalue's context's list of mementos.
2095 Implements the post-error-checking part of
2096 gcc_jit_lvalue_get_address. */
2099 recording::lvalue::get_address (recording::location
*loc
)
2101 recording::rvalue
*result
=
2102 new get_address_of_lvalue (m_ctxt
, loc
, this);
2103 m_ctxt
->record (result
);
2107 /* The implementation of class gcc::jit::recording::param. */
2109 /* Implementation of pure virtual hook recording::memento::replay_into
2110 for recording::param. */
2113 recording::param::replay_into (replayer
*r
)
2115 set_playback_obj (r
->new_param (playback_location (r
, m_loc
),
2116 m_type
->playback_type (),
2121 /* The implementation of class gcc::jit::recording::function. */
2123 /* gcc::jit::recording::function's constructor. */
2125 recording::function::function (context
*ctxt
,
2126 recording::location
*loc
,
2127 enum gcc_jit_function_kind kind
,
2129 recording::string
*name
,
2131 recording::param
**params
,
2133 enum built_in_function builtin_id
)
2137 m_return_type (return_type
),
2140 m_is_variadic (is_variadic
),
2141 m_builtin_id (builtin_id
),
2145 for (int i
= 0; i
< num_params
; i
++)
2146 m_params
.safe_push (params
[i
]);
2149 /* Implementation of pure virtual hook recording::memento::replay_into
2150 for recording::function. */
2153 recording::function::replay_into (replayer
*r
)
2155 /* Convert m_params to a vec of playback param. */
2156 auto_vec
<playback::param
*> params
;
2158 recording::param
*param
;
2159 params
.create (m_params
.length ());
2160 FOR_EACH_VEC_ELT (m_params
, i
, param
)
2161 params
.safe_push (param
->playback_param ());
2163 set_playback_obj (r
->new_function (playback_location (r
, m_loc
),
2165 m_return_type
->playback_type (),
2172 /* Create a recording::local instance and add it to
2173 the functions's context's list of mementos, and to the function's
2176 Implements the post-error-checking part of
2177 gcc_jit_function_new_local. */
2180 recording::function::new_local (recording::location
*loc
,
2184 local
*result
= new local (this, loc
, type
, new_string (name
));
2185 m_ctxt
->record (result
);
2186 m_locals
.safe_push (result
);
2190 /* Create a recording::block instance and add it to
2191 the functions's context's list of mementos, and to the function's
2194 Implements the post-error-checking part of
2195 gcc_jit_function_new_block. */
2198 recording::function::new_block (const char *name
)
2200 gcc_assert (m_kind
!= GCC_JIT_FUNCTION_IMPORTED
);
2202 recording::block
*result
=
2203 new recording::block (this, m_blocks
.length (), new_string (name
));
2204 m_ctxt
->record (result
);
2205 m_blocks
.safe_push (result
);
2209 /* Override the default implementation of
2210 recording::memento::write_to_dump by dumping a C-like
2211 representation of the function; either like a prototype
2212 for GCC_JIT_FUNCTION_IMPORTED, or like a full definition for
2213 all other kinds of function. */
2216 recording::function::write_to_dump (dump
&d
)
2220 default: gcc_unreachable ();
2221 case GCC_JIT_FUNCTION_EXPORTED
:
2222 case GCC_JIT_FUNCTION_IMPORTED
:
2223 d
.write ("extern ");
2225 case GCC_JIT_FUNCTION_INTERNAL
:
2226 d
.write ("static ");
2228 case GCC_JIT_FUNCTION_ALWAYS_INLINE
:
2229 d
.write ("static inline ");
2232 d
.write ("%s\n", m_return_type
->get_debug_string ());
2234 if (d
.update_locations ())
2235 m_loc
= d
.make_location ();
2237 d
.write ("%s (", get_debug_string ());
2240 recording::param
*param
;
2241 FOR_EACH_VEC_ELT (m_params
, i
, param
)
2246 param
->get_type ()->get_debug_string (),
2247 param
->get_debug_string ());
2250 if (m_kind
== GCC_JIT_FUNCTION_IMPORTED
)
2252 d
.write ("; /* (imported) */\n\n");
2262 FOR_EACH_VEC_ELT (m_locals
, i
, var
)
2263 var
->write_to_dump (d
);
2264 if (m_locals
.length ())
2267 /* Write each block: */
2268 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
2272 b
->write_to_dump (d
);
2279 /* Pre-compilation validation of a function, for those things we can't
2280 check until the context is (supposedly) fully-populated. */
2283 recording::function::validate ()
2285 /* Complain about empty functions with non-void return type. */
2286 if (m_kind
!= GCC_JIT_FUNCTION_IMPORTED
2287 && m_return_type
!= m_ctxt
->get_type (GCC_JIT_TYPE_VOID
))
2288 if (0 == m_blocks
.length ())
2289 m_ctxt
->add_error (m_loc
,
2290 "function %s returns non-void (type: %s)"
2291 " but has no blocks",
2292 get_debug_string (),
2293 m_return_type
->get_debug_string ());
2295 /* Check that all blocks are terminated. */
2296 int num_invalid_blocks
= 0;
2301 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
2302 if (!b
->validate ())
2303 num_invalid_blocks
++;
2306 /* Check that all blocks are reachable. */
2307 if (m_blocks
.length () > 0 && 0 == num_invalid_blocks
)
2309 /* Iteratively walk the graph of blocks, marking their "m_is_reachable"
2310 flag, starting at the initial block. */
2311 auto_vec
<block
*> worklist (m_blocks
.length ());
2312 worklist
.safe_push (m_blocks
[0]);
2313 while (worklist
.length () > 0)
2315 block
*b
= worklist
.pop ();
2316 b
->m_is_reachable
= true;
2318 /* Add successor blocks that aren't yet marked to the worklist. */
2319 /* We checked that each block has a terminating statement above . */
2320 block
*next1
, *next2
;
2321 int n
= b
->get_successor_blocks (&next1
, &next2
);
2327 if (!next2
->m_is_reachable
)
2328 worklist
.safe_push (next2
);
2331 if (!next1
->m_is_reachable
)
2332 worklist
.safe_push (next1
);
2339 /* Now complain about any blocks that haven't been marked. */
2343 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
2344 if (!b
->m_is_reachable
)
2345 m_ctxt
->add_error (b
->get_loc (),
2346 "unreachable block: %s",
2347 b
->get_debug_string ());
2352 /* Implements the post-error-checking part of
2353 gcc_jit_function_dump_to_dot. */
2356 recording::function::dump_to_dot (const char *path
)
2358 FILE *fp
= fopen (path
, "w");
2362 pretty_printer the_pp
;
2363 the_pp
.buffer
->stream
= fp
;
2365 pretty_printer
*pp
= &the_pp
;
2368 "digraph %s {\n", get_debug_string ());
2374 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
2375 b
->dump_to_dot (pp
);
2382 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
2383 b
->dump_edges_to_dot (pp
);
2386 pp_printf (pp
, "}\n");
2391 /* Implementation of recording::memento::make_debug_string for
2395 recording::function::make_debug_string ()
2400 /* The implementation of class gcc::jit::recording::block. */
2402 /* Create a recording::eval instance and add it to
2403 the block's context's list of mementos, and to the block's
2406 Implements the post-error-checking part of
2407 gcc_jit_block_add_eval. */
2410 recording::block::add_eval (recording::location
*loc
,
2411 recording::rvalue
*rvalue
)
2413 statement
*result
= new eval (this, loc
, rvalue
);
2414 m_ctxt
->record (result
);
2415 m_statements
.safe_push (result
);
2418 /* Create a recording::assignment instance and add it to
2419 the block's context's list of mementos, and to the block's
2422 Implements the post-error-checking part of
2423 gcc_jit_block_add_assignment. */
2426 recording::block::add_assignment (recording::location
*loc
,
2427 recording::lvalue
*lvalue
,
2428 recording::rvalue
*rvalue
)
2430 statement
*result
= new assignment (this, loc
, lvalue
, rvalue
);
2431 m_ctxt
->record (result
);
2432 m_statements
.safe_push (result
);
2435 /* Create a recording::assignment_op instance and add it to
2436 the block's context's list of mementos, and to the block's
2439 Implements the post-error-checking part of
2440 gcc_jit_block_add_assignment_op. */
2443 recording::block::add_assignment_op (recording::location
*loc
,
2444 recording::lvalue
*lvalue
,
2445 enum gcc_jit_binary_op op
,
2446 recording::rvalue
*rvalue
)
2448 statement
*result
= new assignment_op (this, loc
, lvalue
, op
, rvalue
);
2449 m_ctxt
->record (result
);
2450 m_statements
.safe_push (result
);
2453 /* Create a recording::comment instance and add it to
2454 the block's context's list of mementos, and to the block's
2457 Implements the post-error-checking part of
2458 gcc_jit_block_add_comment. */
2461 recording::block::add_comment (recording::location
*loc
,
2464 statement
*result
= new comment (this, loc
, new_string (text
));
2465 m_ctxt
->record (result
);
2466 m_statements
.safe_push (result
);
2469 /* Create a recording::end_with_conditional instance and add it to
2470 the block's context's list of mementos, and to the block's
2473 Implements the post-error-checking part of
2474 gcc_jit_block_end_with_conditional. */
2477 recording::block::end_with_conditional (recording::location
*loc
,
2478 recording::rvalue
*boolval
,
2479 recording::block
*on_true
,
2480 recording::block
*on_false
)
2482 statement
*result
= new conditional (this, loc
, boolval
, on_true
, on_false
);
2483 m_ctxt
->record (result
);
2484 m_statements
.safe_push (result
);
2485 m_has_been_terminated
= true;
2488 /* Create a recording::end_with_jump instance and add it to
2489 the block's context's list of mementos, and to the block's
2492 Implements the post-error-checking part of
2493 gcc_jit_block_end_with_jump. */
2496 recording::block::end_with_jump (recording::location
*loc
,
2497 recording::block
*target
)
2499 statement
*result
= new jump (this, loc
, target
);
2500 m_ctxt
->record (result
);
2501 m_statements
.safe_push (result
);
2502 m_has_been_terminated
= true;
2505 /* Create a recording::end_with_return instance and add it to
2506 the block's context's list of mementos, and to the block's
2509 Implements the post-error-checking parts of
2510 gcc_jit_block_end_with_return and
2511 gcc_jit_block_end_with_void_return. */
2514 recording::block::end_with_return (recording::location
*loc
,
2515 recording::rvalue
*rvalue
)
2517 /* This is used by both gcc_jit_function_add_return and
2518 gcc_jit_function_add_void_return; rvalue will be non-NULL for
2519 the former and NULL for the latter. */
2520 statement
*result
= new return_ (this, loc
, rvalue
);
2521 m_ctxt
->record (result
);
2522 m_statements
.safe_push (result
);
2523 m_has_been_terminated
= true;
2526 /* Override the default implementation of
2527 recording::memento::write_to_dump for blocks by writing
2528 an unindented block name as a label, followed by the indented
2538 recording::block::write_to_dump (dump
&d
)
2540 d
.write ("%s:\n", get_debug_string ());
2544 FOR_EACH_VEC_ELT (m_statements
, i
, s
)
2545 s
->write_to_dump (d
);
2548 /* Validate a block by ensuring that it has been terminated. */
2551 recording::block::validate ()
2553 if (!has_been_terminated ())
2555 statement
*stmt
= get_last_statement ();
2556 location
*loc
= stmt
? stmt
->get_loc () : NULL
;
2557 m_func
->get_context ()->add_error (loc
,
2558 "unterminated block in %s: %s",
2559 m_func
->get_debug_string (),
2560 get_debug_string ());
2567 /* Get the source-location of a block by using that of the first
2568 statement within it, if any. */
2570 recording::location
*
2571 recording::block::get_loc () const
2573 recording::statement
*stmt
= get_first_statement ();
2575 return stmt
->get_loc ();
2580 /* Get the first statement within a block, if any. */
2582 recording::statement
*
2583 recording::block::get_first_statement () const
2585 if (m_statements
.length ())
2586 return m_statements
[0];
2591 /* Get the last statement within a block, if any. */
2593 recording::statement
*
2594 recording::block::get_last_statement () const
2596 if (m_statements
.length ())
2597 return m_statements
[m_statements
.length () - 1];
2602 /* Assuming that this block has been terminated, get the number of
2603 successor blocks, which will be 0, 1 or 2, for return, unconditional
2604 jump, and conditional jump respectively.
2605 NEXT1 and NEXT2 must be non-NULL. The first successor block (if any)
2606 is written to NEXT1, and the second (if any) to NEXT2.
2608 Used when validating functions, and when dumping dot representations
2612 recording::block::get_successor_blocks (block
**next1
, block
**next2
) const
2614 gcc_assert (m_has_been_terminated
);
2617 statement
*last_statement
= get_last_statement ();
2618 gcc_assert (last_statement
);
2619 return last_statement
->get_successor_blocks (next1
, next2
);
2622 /* Implementation of pure virtual hook recording::memento::replay_into
2623 for recording::block. */
2626 recording::block::replay_into (replayer
*)
2628 set_playback_obj (m_func
->playback_function ()
2629 ->new_block (playback_string (m_name
)));
2632 /* Implementation of recording::memento::make_debug_string for
2636 recording::block::make_debug_string ()
2641 return string::from_printf (m_ctxt
,
2642 "<UNNAMED BLOCK %p>",
2646 /* Dump a block in graphviz form into PP, capturing the block name (if
2647 any) and the statements. */
2650 recording::block::dump_to_dot (pretty_printer
*pp
)
2654 "[shape=record,style=filled,fillcolor=white,label=\"{"),
2656 pp_write_text_to_stream (pp
);
2659 pp_string (pp
, m_name
->c_str ());
2660 pp_string (pp
, ":");
2662 pp_write_text_as_dot_label_to_stream (pp
, true /*for_record*/);
2667 FOR_EACH_VEC_ELT (m_statements
, i
, s
)
2669 pp_string (pp
, s
->get_debug_string ());
2671 pp_write_text_as_dot_label_to_stream (pp
, true /*for_record*/);
2679 /* Dump the out-edges of the block in graphviz form into PP. */
2682 recording::block::dump_edges_to_dot (pretty_printer
*pp
)
2685 int num_succs
= get_successor_blocks (&next
[0], &next
[1]);
2686 for (int i
= 0; i
< num_succs
; i
++)
2688 "\tblock_%d:s -> block_%d:n;\n",
2689 m_index
, next
[i
]->m_index
);
2692 /* The implementation of class gcc::jit::recording::global. */
2694 /* Implementation of pure virtual hook recording::memento::replay_into
2695 for recording::global. */
2698 recording::global::replay_into (replayer
*r
)
2700 set_playback_obj (r
->new_global (playback_location (r
, m_loc
),
2701 m_type
->playback_type (),
2702 playback_string (m_name
)));
2705 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_int. */
2707 /* Implementation of pure virtual hook recording::memento::replay_into
2708 for recording::memento_of_new_rvalue_from_int. */
2711 recording::memento_of_new_rvalue_from_int::replay_into (replayer
*r
)
2713 set_playback_obj (r
->new_rvalue_from_int (m_type
->playback_type (),
2717 /* Implementation of recording::memento::make_debug_string for
2718 rvalue_from_int, rendering it as
2724 recording::memento_of_new_rvalue_from_int::make_debug_string ()
2726 return string::from_printf (m_ctxt
,
2728 m_type
->get_debug_string (),
2732 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_double. */
2734 /* Implementation of pure virtual hook recording::memento::replay_into
2735 for recording::memento_of_new_rvalue_from_double. */
2738 recording::memento_of_new_rvalue_from_double::replay_into (replayer
*r
)
2740 set_playback_obj (r
->new_rvalue_from_double (m_type
->playback_type (),
2744 /* Implementation of recording::memento::make_debug_string for
2745 rvalue_from_double, rendering it as
2751 recording::memento_of_new_rvalue_from_double::make_debug_string ()
2753 return string::from_printf (m_ctxt
,
2755 m_type
->get_debug_string (),
2759 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_ptr. */
2761 /* Implementation of pure virtual hook recording::memento::replay_into
2762 for recording::memento_of_new_rvalue_from_ptr. */
2765 recording::memento_of_new_rvalue_from_ptr::replay_into (replayer
*r
)
2767 set_playback_obj (r
->new_rvalue_from_ptr (m_type
->playback_type (),
2771 /* Implementation of recording::memento::make_debug_string for
2772 rvalue_from_ptr, rendering it as
2777 Zero is rendered as NULL e.g.
2781 recording::memento_of_new_rvalue_from_ptr::make_debug_string ()
2783 if (m_value
!= NULL
)
2784 return string::from_printf (m_ctxt
,
2786 m_type
->get_debug_string (), m_value
);
2788 return string::from_printf (m_ctxt
,
2790 m_type
->get_debug_string ());
2793 /* The implementation of class gcc::jit::recording::memento_of_new_string_literal. */
2795 /* Implementation of pure virtual hook recording::memento::replay_into
2796 for recording::memento_of_new_string_literal. */
2799 recording::memento_of_new_string_literal::replay_into (replayer
*r
)
2801 set_playback_obj (r
->new_string_literal (m_value
->c_str ()));
2804 /* Implementation of recording::memento::make_debug_string for
2808 recording::memento_of_new_string_literal::make_debug_string ()
2810 return string::from_printf (m_ctxt
,
2811 m_value
->get_debug_string ());
2814 /* The implementation of class gcc::jit::recording::unary_op. */
2816 /* Implementation of pure virtual hook recording::memento::replay_into
2817 for recording::unary_op. */
2820 recording::unary_op::replay_into (replayer
*r
)
2822 set_playback_obj (r
->new_unary_op (playback_location (r
, m_loc
),
2824 get_type ()->playback_type (),
2825 m_a
->playback_rvalue ()));
2828 /* Implementation of recording::memento::make_debug_string for
2831 static const char * const unary_op_strings
[] = {
2832 "-", /* GCC_JIT_UNARY_OP_MINUS */
2833 "~", /* GCC_JIT_UNARY_OP_BITWISE_NEGATE */
2834 "!", /* GCC_JIT_UNARY_OP_LOGICAL_NEGATE */
2835 "abs ", /* GCC_JIT_UNARY_OP_ABS */
2839 recording::unary_op::make_debug_string ()
2841 return string::from_printf (m_ctxt
,
2843 unary_op_strings
[m_op
],
2844 m_a
->get_debug_string ());
2847 /* The implementation of class gcc::jit::recording::binary_op. */
2849 /* Implementation of pure virtual hook recording::memento::replay_into
2850 for recording::binary_op. */
2853 recording::binary_op::replay_into (replayer
*r
)
2855 set_playback_obj (r
->new_binary_op (playback_location (r
, m_loc
),
2857 get_type ()->playback_type (),
2858 m_a
->playback_rvalue (),
2859 m_b
->playback_rvalue ()));
2862 /* Implementation of recording::memento::make_debug_string for
2865 static const char * const binary_op_strings
[] = {
2866 "+", /* GCC_JIT_BINARY_OP_PLUS */
2867 "-", /* GCC_JIT_BINARY_OP_MINUS */
2868 "*", /* GCC_JIT_BINARY_OP_MULT */
2869 "/", /* GCC_JIT_BINARY_OP_DIVIDE */
2870 "%", /* GCC_JIT_BINARY_OP_MODULO */
2871 "&", /* GCC_JIT_BINARY_OP_BITWISE_AND */
2872 "^", /* GCC_JIT_BINARY_OP_BITWISE_XOR */
2873 "|", /* GCC_JIT_BINARY_OP_BITWISE_OR */
2874 "&&", /* GCC_JIT_BINARY_OP_LOGICAL_AND */
2875 "||", /* GCC_JIT_BINARY_OP_LOGICAL_OR */
2876 "<<", /* GCC_JIT_BINARY_OP_LSHIFT */
2877 ">>", /* GCC_JIT_BINARY_OP_RSHIFT */
2881 recording::binary_op::make_debug_string ()
2883 return string::from_printf (m_ctxt
,
2885 m_a
->get_debug_string (),
2886 binary_op_strings
[m_op
],
2887 m_b
->get_debug_string ());
2890 /* The implementation of class gcc::jit::recording::comparison. */
2892 /* Implementation of recording::memento::make_debug_string for
2895 static const char * const comparison_strings
[] =
2897 "==", /* GCC_JIT_COMPARISON_EQ */
2898 "!=", /* GCC_JIT_COMPARISON_NE */
2899 "<", /* GCC_JIT_COMPARISON_LT */
2900 "<=", /* GCC_JIT_COMPARISON_LE */
2901 ">", /* GCC_JIT_COMPARISON_GT */
2902 ">=", /* GCC_JIT_COMPARISON_GE */
2906 recording::comparison::make_debug_string ()
2908 return string::from_printf (m_ctxt
,
2910 m_a
->get_debug_string (),
2911 comparison_strings
[m_op
],
2912 m_b
->get_debug_string ());
2915 /* Implementation of pure virtual hook recording::memento::replay_into
2916 for recording::comparison. */
2919 recording::comparison::replay_into (replayer
*r
)
2921 set_playback_obj (r
->new_comparison (playback_location (r
, m_loc
),
2923 m_a
->playback_rvalue (),
2924 m_b
->playback_rvalue ()));
2927 /* Implementation of pure virtual hook recording::memento::replay_into
2928 for recording::cast. */
2931 recording::cast::replay_into (replayer
*r
)
2933 set_playback_obj (r
->new_cast (playback_location (r
, m_loc
),
2934 m_rvalue
->playback_rvalue (),
2935 get_type ()->playback_type ()));
2938 /* Implementation of recording::memento::make_debug_string for
2942 recording::cast::make_debug_string ()
2944 return string::from_printf (m_ctxt
,
2946 get_type ()->get_debug_string (),
2947 m_rvalue
->get_debug_string ());
2950 /* The implementation of class gcc::jit::recording::call. */
2952 /* The constructor for gcc::jit::recording::call. */
2954 recording::call::call (recording::context
*ctxt
,
2955 recording::location
*loc
,
2956 recording::function
*func
,
2959 : rvalue (ctxt
, loc
, func
->get_return_type ()),
2963 for (int i
= 0; i
< numargs
; i
++)
2964 m_args
.safe_push (args
[i
]);
2967 /* Implementation of pure virtual hook recording::memento::replay_into
2968 for recording::call. */
2971 recording::call::replay_into (replayer
*r
)
2973 auto_vec
<playback::rvalue
*> playback_args
;
2974 playback_args
.create (m_args
.length ());
2975 for (unsigned i
= 0; i
< m_args
.length (); i
++)
2976 playback_args
.safe_push (m_args
[i
]->playback_rvalue ());
2978 set_playback_obj (r
->new_call (playback_location (r
, m_loc
),
2979 m_func
->playback_function (),
2983 /* Implementation of recording::memento::make_debug_string for
2987 recording::call::make_debug_string ()
2989 /* First, build a buffer for the arguments. */
2990 /* Calculate length of said buffer. */
2991 size_t sz
= 1; /* nil terminator */
2992 for (unsigned i
= 0; i
< m_args
.length (); i
++)
2994 sz
+= strlen (m_args
[i
]->get_debug_string ());
2995 sz
+= 2; /* ", " separator */
2998 /* Now allocate and populate the buffer. */
2999 char *argbuf
= new char[sz
];
3002 for (unsigned i
= 0; i
< m_args
.length (); i
++)
3004 strcpy (argbuf
+ len
, m_args
[i
]->get_debug_string ());
3005 len
+= strlen (m_args
[i
]->get_debug_string ());
3006 if (i
+ 1 < m_args
.length ())
3008 strcpy (argbuf
+ len
, ", ");
3014 /* ...and use it to get the string for the call as a whole. */
3015 string
*result
= string::from_printf (m_ctxt
,
3017 m_func
->get_debug_string (),
3025 /* The implementation of class gcc::jit::recording::call_through_ptr. */
3027 /* The constructor for recording::call_through_ptr. */
3029 recording::call_through_ptr::call_through_ptr (recording::context
*ctxt
,
3030 recording::location
*loc
,
3031 recording::rvalue
*fn_ptr
,
3034 : rvalue (ctxt
, loc
,
3035 fn_ptr
->get_type ()->dereference ()
3036 ->as_a_function_type ()->get_return_type ()),
3040 for (int i
= 0; i
< numargs
; i
++)
3041 m_args
.safe_push (args
[i
]);
3044 /* Implementation of pure virtual hook recording::memento::replay_into
3045 for recording::call_through_ptr. */
3048 recording::call_through_ptr::replay_into (replayer
*r
)
3050 auto_vec
<playback::rvalue
*> playback_args
;
3051 playback_args
.create (m_args
.length ());
3052 for (unsigned i
= 0; i
< m_args
.length (); i
++)
3053 playback_args
.safe_push (m_args
[i
]->playback_rvalue ());
3055 set_playback_obj (r
->new_call_through_ptr (playback_location (r
, m_loc
),
3056 m_fn_ptr
->playback_rvalue (),
3060 /* Implementation of recording::memento::make_debug_string for
3061 calls through function ptrs. */
3064 recording::call_through_ptr::make_debug_string ()
3066 /* First, build a buffer for the arguments. */
3067 /* Calculate length of said buffer. */
3068 size_t sz
= 1; /* nil terminator */
3069 for (unsigned i
= 0; i
< m_args
.length (); i
++)
3071 sz
+= strlen (m_args
[i
]->get_debug_string ());
3072 sz
+= 2; /* ", " separator */
3075 /* Now allocate and populate the buffer. */
3076 char *argbuf
= new char[sz
];
3079 for (unsigned i
= 0; i
< m_args
.length (); i
++)
3081 strcpy (argbuf
+ len
, m_args
[i
]->get_debug_string ());
3082 len
+= strlen (m_args
[i
]->get_debug_string ());
3083 if (i
+ 1 < m_args
.length ())
3085 strcpy (argbuf
+ len
, ", ");
3091 /* ...and use it to get the string for the call as a whole. */
3092 string
*result
= string::from_printf (m_ctxt
,
3094 m_fn_ptr
->get_debug_string (),
3102 /* The implementation of class gcc::jit::recording::array_access. */
3104 /* Implementation of pure virtual hook recording::memento::replay_into
3105 for recording::array_access. */
3108 recording::array_access::replay_into (replayer
*r
)
3111 r
->new_array_access (playback_location (r
, m_loc
),
3112 m_ptr
->playback_rvalue (),
3113 m_index
->playback_rvalue ()));
3116 /* Implementation of recording::memento::make_debug_string for
3120 recording::array_access::make_debug_string ()
3122 return string::from_printf (m_ctxt
,
3124 m_ptr
->get_debug_string (),
3125 m_index
->get_debug_string ());
3128 /* The implementation of class gcc::jit::recording::access_field_of_lvalue. */
3130 /* Implementation of pure virtual hook recording::memento::replay_into
3131 for recording::access_field_of_lvalue. */
3134 recording::access_field_of_lvalue::replay_into (replayer
*r
)
3137 m_lvalue
->playback_lvalue ()
3138 ->access_field (playback_location (r
, m_loc
),
3139 m_field
->playback_field ()));
3143 /* Implementation of recording::memento::make_debug_string for
3144 accessing a field of an lvalue. */
3147 recording::access_field_of_lvalue::make_debug_string ()
3149 return string::from_printf (m_ctxt
,
3151 m_lvalue
->get_debug_string (),
3152 m_field
->get_debug_string ());
3155 /* The implementation of class gcc::jit::recording::access_field_rvalue. */
3157 /* Implementation of pure virtual hook recording::memento::replay_into
3158 for recording::access_field_rvalue. */
3161 recording::access_field_rvalue::replay_into (replayer
*r
)
3164 m_rvalue
->playback_rvalue ()
3165 ->access_field (playback_location (r
, m_loc
),
3166 m_field
->playback_field ()));
3169 /* Implementation of recording::memento::make_debug_string for
3170 accessing a field of an rvalue. */
3173 recording::access_field_rvalue::make_debug_string ()
3175 return string::from_printf (m_ctxt
,
3177 m_rvalue
->get_debug_string (),
3178 m_field
->get_debug_string ());
3181 /* The implementation of class
3182 gcc::jit::recording::dereference_field_rvalue. */
3184 /* Implementation of pure virtual hook recording::memento::replay_into
3185 for recording::dereference_field_rvalue. */
3188 recording::dereference_field_rvalue::replay_into (replayer
*r
)
3191 m_rvalue
->playback_rvalue ()->
3192 dereference_field (playback_location (r
, m_loc
),
3193 m_field
->playback_field ()));
3196 /* Implementation of recording::memento::make_debug_string for
3197 dereferencing a field of an rvalue. */
3200 recording::dereference_field_rvalue::make_debug_string ()
3202 return string::from_printf (m_ctxt
,
3204 m_rvalue
->get_debug_string (),
3205 m_field
->get_debug_string ());
3208 /* The implementation of class gcc::jit::recording::dereference_rvalue. */
3210 /* Implementation of pure virtual hook recording::memento::replay_into
3211 for recording::dereference_rvalue. */
3214 recording::dereference_rvalue::replay_into (replayer
*r
)
3217 m_rvalue
->playback_rvalue ()->
3218 dereference (playback_location (r
, m_loc
)));
3221 /* Implementation of recording::memento::make_debug_string for
3222 dereferencing an rvalue. */
3225 recording::dereference_rvalue::make_debug_string ()
3227 return string::from_printf (m_ctxt
,
3229 m_rvalue
->get_debug_string ());
3232 /* The implementation of class gcc::jit::recording::get_address_of_lvalue. */
3234 /* Implementation of pure virtual hook recording::memento::replay_into
3235 for recording::get_address_of_lvalue. */
3238 recording::get_address_of_lvalue::replay_into (replayer
*r
)
3241 m_lvalue
->playback_lvalue ()->
3242 get_address (playback_location (r
, m_loc
)));
3245 /* Implementation of recording::memento::make_debug_string for
3246 getting the address of an lvalue. */
3249 recording::get_address_of_lvalue::make_debug_string ()
3251 return string::from_printf (m_ctxt
,
3253 m_lvalue
->get_debug_string ());
3256 /* The implementation of class gcc::jit::recording::local. */
3258 /* Implementation of pure virtual hook recording::memento::replay_into
3259 for recording::local. */
3262 recording::local::replay_into (replayer
*r
)
3265 m_func
->playback_function ()
3266 ->new_local (playback_location (r
, m_loc
),
3267 m_type
->playback_type (),
3268 playback_string (m_name
)));
3271 /* Override the default implementation of
3272 recording::memento::write_to_dump for locals by writing
3274 for use at the top of the function body as if it were a
3278 recording::local::write_to_dump (dump
&d
)
3280 if (d
.update_locations ())
3281 m_loc
= d
.make_location ();
3282 d
.write(" %s %s;\n",
3283 m_type
->get_debug_string (),
3284 get_debug_string ());
3287 /* The implementation of class gcc::jit::recording::statement. */
3289 /* We poison the default implementation of
3290 gcc::jit::recording::statement::get_successor_blocks
3291 since this vfunc must only ever be called on terminator
3295 recording::statement::get_successor_blocks (block
**/
*out_next1*/
,
3296 block
**/
*out_next2*/
) const
3298 /* The base class implementation is for non-terminating statements,
3299 and thus should never be called. */
3304 /* Extend the default implementation of
3305 recording::memento::write_to_dump for statements by (if requested)
3306 updating the location of the statement to the current location in
3310 recording::statement::write_to_dump (dump
&d
)
3312 memento::write_to_dump (d
);
3313 if (d
.update_locations ())
3314 m_loc
= d
.make_location ();
3317 /* The implementation of class gcc::jit::recording::eval. */
3319 /* Implementation of pure virtual hook recording::memento::replay_into
3320 for recording::eval. */
3323 recording::eval::replay_into (replayer
*r
)
3325 playback_block (get_block ())
3326 ->add_eval (playback_location (r
),
3327 m_rvalue
->playback_rvalue ());
3330 /* Implementation of recording::memento::make_debug_string for
3331 an eval statement. */
3334 recording::eval::make_debug_string ()
3336 return string::from_printf (m_ctxt
,
3338 m_rvalue
->get_debug_string ());
3341 /* The implementation of class gcc::jit::recording::assignment. */
3343 /* Implementation of pure virtual hook recording::memento::replay_into
3344 for recording::assignment. */
3347 recording::assignment::replay_into (replayer
*r
)
3349 playback_block (get_block ())
3350 ->add_assignment (playback_location (r
),
3351 m_lvalue
->playback_lvalue (),
3352 m_rvalue
->playback_rvalue ());
3355 /* Implementation of recording::memento::make_debug_string for
3356 an assignment statement. */
3359 recording::assignment::make_debug_string ()
3361 return string::from_printf (m_ctxt
,
3363 m_lvalue
->get_debug_string (),
3364 m_rvalue
->get_debug_string ());
3367 /* The implementation of class gcc::jit::recording::assignment_op. */
3369 /* Implementation of pure virtual hook recording::memento::replay_into
3370 for recording::assignment_op. */
3373 recording::assignment_op::replay_into (replayer
*r
)
3375 playback::type
*result_type
=
3376 m_lvalue
->playback_lvalue ()->get_type ();
3378 playback::rvalue
*binary_op
=
3379 r
->new_binary_op (playback_location (r
),
3382 m_lvalue
->playback_rvalue (),
3383 m_rvalue
->playback_rvalue ());
3385 playback_block (get_block ())
3386 ->add_assignment (playback_location (r
),
3387 m_lvalue
->playback_lvalue (),
3391 /* Implementation of recording::memento::make_debug_string for
3392 an assignment_op statement. */
3395 recording::assignment_op::make_debug_string ()
3397 return string::from_printf (m_ctxt
,
3399 m_lvalue
->get_debug_string (),
3400 binary_op_strings
[m_op
],
3401 m_rvalue
->get_debug_string ());
3404 /* The implementation of class gcc::jit::recording::comment. */
3406 /* Implementation of pure virtual hook recording::memento::replay_into
3407 for recording::comment. */
3410 recording::comment::replay_into (replayer
*r
)
3412 playback_block (get_block ())
3413 ->add_comment (playback_location (r
),
3417 /* Implementation of recording::memento::make_debug_string for
3418 a comment "statement". */
3421 recording::comment::make_debug_string ()
3423 return string::from_printf (m_ctxt
,
3428 /* The implementation of class gcc::jit::recording::conditional. */
3430 /* Implementation of pure virtual hook recording::memento::replay_into
3431 for recording::conditional. */
3434 recording::conditional::replay_into (replayer
*r
)
3436 playback_block (get_block ())
3437 ->add_conditional (playback_location (r
),
3438 m_boolval
->playback_rvalue (),
3439 playback_block (m_on_true
),
3440 playback_block (m_on_false
));
3443 /* Override the poisoned default implementation of
3444 gcc::jit::recording::statement::get_successor_blocks
3446 A conditional jump has 2 successor blocks. */
3449 recording::conditional::get_successor_blocks (block
**out_next1
,
3450 block
**out_next2
) const
3452 *out_next1
= m_on_true
;
3453 *out_next2
= m_on_false
;
3457 /* Implementation of recording::memento::make_debug_string for
3458 a conditional jump statement. */
3461 recording::conditional::make_debug_string ()
3464 return string::from_printf (m_ctxt
,
3465 "if (%s) goto %s; else goto %s;",
3466 m_boolval
->get_debug_string (),
3467 m_on_true
->get_debug_string (),
3468 m_on_false
->get_debug_string ());
3470 return string::from_printf (m_ctxt
,
3472 m_boolval
->get_debug_string (),
3473 m_on_true
->get_debug_string ());
3476 /* The implementation of class gcc::jit::recording::jump. */
3478 /* Implementation of pure virtual hook recording::memento::replay_into
3479 for recording::jump. */
3482 recording::jump::replay_into (replayer
*r
)
3484 playback_block (get_block ())
3485 ->add_jump (playback_location (r
),
3486 m_target
->playback_block ());
3489 /* Override the poisoned default implementation of
3490 gcc::jit::recording::statement::get_successor_blocks
3492 An unconditional jump has 1 successor block. */
3495 recording::jump::get_successor_blocks (block
**out_next1
,
3496 block
**/
*out_next2*/
) const
3498 *out_next1
= m_target
;
3502 /* Implementation of recording::memento::make_debug_string for
3503 a unconditional jump statement. */
3506 recording::jump::make_debug_string ()
3508 return string::from_printf (m_ctxt
,
3510 m_target
->get_debug_string ());
3513 /* The implementation of class gcc::jit::recording::return_. */
3515 /* Implementation of pure virtual hook recording::memento::replay_into
3516 for recording::return_. */
3519 recording::return_::replay_into (replayer
*r
)
3521 playback_block (get_block ())
3522 ->add_return (playback_location (r
),
3523 m_rvalue
? m_rvalue
->playback_rvalue () : NULL
);
3526 /* Override the poisoned default implementation of
3527 gcc::jit::recording::statement::get_successor_blocks
3529 A return statement has no successor block. */
3532 recording::return_::get_successor_blocks (block
**/
*out_next1*/
,
3533 block
**/
*out_next2*/
) const
3538 /* Implementation of recording::memento::make_debug_string for
3539 a return statement (covers both those with and without rvalues). */
3542 recording::return_::make_debug_string ()
3545 return string::from_printf (m_ctxt
,
3547 m_rvalue
->get_debug_string ());
3549 return string::from_printf (m_ctxt
,
3553 } // namespace gcc::jit