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),
182 m_builtins_manager(NULL
)
186 /* Inherit options from parent. */
188 i
< sizeof (m_str_options
) / sizeof (m_str_options
[0]);
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 ());
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 ());
220 FOR_EACH_VEC_ELT (m_mementos
, i
, 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. */
240 recording::context::record (memento
*m
)
244 m_mementos
.safe_push (m
);
247 /* Replay this context (and any parents) into the given replayer. */
250 recording::context::replay_into (replayer
*r
)
252 JIT_LOG_SCOPE (get_logger ());
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). */
272 m_parent_ctxt
->replay_into (r
);
274 if (r
->errors_occurred ())
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
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
287 printf ("context %p replaying (%p): %s\n",
288 (void *)this, (void *)m
, m
->get_debug_string ());
292 if (r
->errors_occurred ())
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). */
308 recording::context::disassociate_from_playback ()
310 JIT_LOG_SCOPE (get_logger ());
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
326 This creates a fresh copy of the given 0-terminated buffer. */
329 recording::context::new_string (const char *text
)
334 recording::string
*result
= new string (this, text
);
339 /* Create a recording::location instance and add it to this context's
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
,
350 recording::location
*result
=
351 new recording::location (this,
352 new_string (filename
),
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
367 Implements the post-error-checking part of
368 gcc_jit_context_get_type. */
371 recording::context::get_type (enum gcc_jit_types kind
)
373 if (!m_basic_types
[kind
])
376 m_basic_types
[kind
] = m_parent_ctxt
->get_type (kind
);
379 recording::type
*result
= new memento_of_get_type (this, kind
);
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
392 Implements the post-error-checking part of
393 gcc_jit_context_get_int_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
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
416 : GCC_JIT_TYPE_UNSIGNED_SHORT
);
417 if (num_bits
== LONG_TYPE_SIZE
)
418 return get_type (is_signed
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? */
432 /* Create a recording::type instance and add it to this context's list
435 Implements the post-error-checking part of
436 gcc_jit_context_new_array_type. */
439 recording::context::new_array_type (recording::location
*loc
,
440 recording::type
*element_type
,
443 if (struct_
*s
= element_type
->dyn_cast_struct ())
444 if (!s
->get_fields ())
447 "cannot create an array of type %s"
448 " until the fields have been set",
449 s
->get_name ()->c_str ());
452 recording::type
*result
=
453 new recording::array_type (this, loc
, element_type
, num_elements
);
458 /* Create a recording::field instance and add it to this context's list
461 Implements the post-error-checking part of
462 gcc_jit_context_new_field. */
465 recording::context::new_field (recording::location
*loc
,
466 recording::type
*type
,
469 recording::field
*result
=
470 new recording::field (this, loc
, type
, new_string (name
));
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. */
482 recording::context::new_struct_type (recording::location
*loc
,
485 recording::struct_
*result
= new struct_ (this, loc
, new_string (name
));
487 m_compound_types
.safe_push (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. */
498 recording::context::new_union_type (recording::location
*loc
,
501 recording::union_
*result
= new union_ (this, loc
, new_string (name
));
503 m_compound_types
.safe_push (result
);
507 /* Create a recording::function_type instance and add it to this context's
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
,
515 recording::type
**param_types
,
518 recording::function_type
*fn_type
519 = new function_type (this,
528 /* Create a recording::type instance and add it to this context's list
531 Implements the post-error-checking part of
532 gcc_jit_context_new_function_ptr_type. */
535 recording::context::new_function_ptr_type (recording::location
*, /* unused loc */
536 recording::type
*return_type
,
538 recording::type
**param_types
,
541 recording::function_type
*fn_type
542 = new_function_type (return_type
,
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
554 Implements the post-error-checking part of
555 gcc_jit_context_new_param. */
558 recording::context::new_param (recording::location
*loc
,
559 recording::type
*type
,
562 recording::param
*result
= new recording::param (this, loc
, type
, new_string (name
));
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
,
579 recording::param
**params
,
581 enum built_in_function builtin_id
)
583 recording::function
*result
=
584 new recording::function (this,
585 loc
, kind
, return_type
,
587 num_params
, params
, is_variadic
,
590 m_functions
.safe_push (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. */
603 recording::context::get_builtins_manager ()
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
630 Implements the post-error-checking part of
631 gcc_jit_context_new_global. */
634 recording::context::new_global (recording::location
*loc
,
635 recording::type
*type
,
638 recording::lvalue
*result
=
639 new recording::global (this, loc
, type
, new_string (name
));
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. */
651 recording::context::new_rvalue_from_int (recording::type
*type
,
654 recording::rvalue
*result
=
655 new memento_of_new_rvalue_from_int (this, NULL
, type
, value
);
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. */
667 recording::context::new_rvalue_from_double (recording::type
*type
,
670 recording::rvalue
*result
=
671 new memento_of_new_rvalue_from_double (this, NULL
, type
, value
);
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. */
683 recording::context::new_rvalue_from_ptr (recording::type
*type
,
686 recording::rvalue
*result
=
687 new memento_of_new_rvalue_from_ptr (this, NULL
, type
, value
);
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. */
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
));
707 /* Create a recording::unary_op instance and add it to this context's
710 Implements the post-error-checking part of
711 gcc_jit_context_new_unary_op. */
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
);
725 /* Create a recording::binary_op instance and add it to this context's
728 Implements the post-error-checking part of
729 gcc_jit_context_new_binary_op. */
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
);
744 /* Create a recording::comparison instance and add it to this context's
747 Implements the post-error-checking part of
748 gcc_jit_context_new_comparison. */
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
);
761 /* Create a recording::cast instance and add it to this context's list
764 Implements the post-error-checking part of
765 gcc_jit_context_new_cast. */
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_
);
777 /* Create a recording::call instance and add it to this context's list
780 Implements the post-error-checking part of
781 gcc_jit_context_new_call. */
784 recording::context::new_call (recording::location
*loc
,
786 int numargs
, recording::rvalue
**args
)
788 recording::rvalue
*result
= new call (this, loc
, func
, numargs
, args
);
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. */
800 recording::context::new_call_through_ptr (recording::location
*loc
,
801 recording::rvalue
*fn_ptr
,
803 recording::rvalue
**args
)
805 recording::rvalue
*result
= new call_through_ptr (this, loc
, fn_ptr
, numargs
, args
);
810 /* Create a recording::array_access instance and add it to this context's list
813 Implements the post-error-checking part of
814 gcc_jit_context_new_array_access. */
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
);
826 /* Set the given string option for this context, or add an error if
829 Implements the post-error-checking part of
830 gcc_jit_context_set_str_option. */
833 recording::context::set_str_option (enum gcc_jit_str_option opt
,
836 if (opt
< 0 || opt
>= GCC_JIT_NUM_STR_OPTIONS
)
839 "unrecognized (enum gcc_jit_str_option) value: %i", opt
);
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
849 Implements the post-error-checking part of
850 gcc_jit_context_set_int_option. */
853 recording::context::set_int_option (enum gcc_jit_int_option opt
,
856 if (opt
< 0 || opt
>= GCC_JIT_NUM_INT_OPTIONS
)
859 "unrecognized (enum gcc_jit_int_option) value: %i", opt
);
862 m_int_options
[opt
] = value
;
865 /* Set the given boolean option for this context, or add an error if
868 Implements the post-error-checking part of
869 gcc_jit_context_set_bool_option. */
872 recording::context::set_bool_option (enum gcc_jit_bool_option opt
,
875 if (opt
< 0 || opt
>= GCC_JIT_NUM_BOOL_OPTIONS
)
878 "unrecognized (enum gcc_jit_bool_option) value: %i", opt
);
881 m_bool_options
[opt
] = value
? true : false;
884 /* Add the given dumpname/out_ptr pair to this context's list of requested
887 Implements the post-error-checking part of
888 gcc_jit_context_enable_dump. */
891 recording::context::enable_dump (const char *dumpname
,
895 gcc_assert (dumpname
);
896 gcc_assert (out_ptr
);
898 d
.m_dumpname
= dumpname
;
899 d
.m_out_ptr
= out_ptr
;
901 m_requested_dumps
.safe_push (d
);
904 /* Validate this context, and if it passes, compile it within a
907 Implements the post-error-checking part of
908 gcc_jit_context_compile. */
911 recording::context::compile ()
913 JIT_LOG_SCOPE (get_logger ());
917 if (errors_occurred ())
920 /* Set up a playback context. */
921 ::gcc::jit::playback::context
replayer (this);
924 result
*result_obj
= replayer
.compile ();
929 /* Format the given error using printf's conventions, print
930 it to stderr, and add it to the context. */
933 recording::context::add_error (location
*loc
, const char *fmt
, ...)
937 add_error_va (loc
, fmt
, ap
);
941 /* Format the given error using printf's conventions, print
942 it to stderr, and add it to the context. */
945 recording::context::add_error_va (location
*loc
, const char *fmt
, va_list ap
)
951 JIT_LOG_SCOPE (get_logger ());
953 vasprintf (&malloced_msg
, fmt
, ap
);
956 errmsg
= malloced_msg
;
957 has_ownership
= true;
961 errmsg
= "out of memory generating error message";
962 has_ownership
= false;
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
);
970 ctxt_progname
= "libgccjit.so";
973 fprintf (stderr
, "%s: %s: error: %s\n",
975 loc
->get_debug_string (),
978 fprintf (stderr
, "%s: error: %s\n",
984 m_first_error_str
= const_cast <char *> (errmsg
);
985 m_owns_first_error_str
= has_ownership
;
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. */
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). */
1013 recording::context::get_opaque_FILE_type ()
1016 m_FILE_type
= new_struct_type (NULL
, "FILE");
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. */
1028 recording::context::dump_to_file (const char *path
, bool update_locations
)
1031 dump
d (*this, path
, update_locations
);
1033 /* Forward declaration of structs and unions. */
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
);
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
1059 recording::context::get_all_requested_dumps (vec
<recording::requested_dump
> *out
)
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. */
1073 recording::context::validate ()
1075 JIT_LOG_SCOPE (get_logger ());
1078 m_parent_ctxt
->validate ();
1082 FOR_EACH_VEC_ELT (m_functions
, i
, fn
)
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
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
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. */
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
)
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 ()
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. */
1141 recording::string::from_printf (context
*ctxt
, const char *fmt
, ...)
1145 recording::string
*result
;
1148 vasprintf (&buf
, fmt
, ap
);
1153 ctxt
->add_error (NULL
, "malloc failure");
1157 result
= ctxt
->new_string (buf
);
1162 /* Implementation of recording::memento::make_debug_string for strings,
1163 wrapping the given string in quotes and escaping as necessary. */
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] == '"')
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
];
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
== '"')
1191 APPEND('"'); /* closing quote */
1193 tmp
[len
] = '\0'; /* nil termintator */
1195 string
*result
= m_ctxt
->new_string (tmp
);
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. */
1209 recording::location::replay_into (replayer
*r
)
1211 m_playback_obj
= r
->new_location (this,
1212 m_filename
->c_str (),
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. */
1223 recording::location::make_debug_string ()
1225 return string::from_printf (m_ctxt
,
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. */
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. */
1259 recording::type::get_const ()
1261 recording::type
*result
= new memento_of_get_const (this);
1262 m_ctxt
->record (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. */
1272 recording::type::get_volatile ()
1274 recording::type
*result
= new memento_of_get_volatile (this);
1275 m_ctxt
->record (result
);
1279 /* Implementation of pure virtual hook recording::type::dereference for
1280 recording::memento_of_get_type. */
1283 recording::memento_of_get_type::dereference ()
1287 default: gcc_unreachable ();
1289 case GCC_JIT_TYPE_VOID
:
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: */
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: */
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. */
1333 recording::memento_of_get_type::is_int () const
1337 default: gcc_unreachable ();
1339 case GCC_JIT_TYPE_VOID
:
1342 case GCC_JIT_TYPE_VOID_PTR
:
1345 case GCC_JIT_TYPE_BOOL
:
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
:
1361 case GCC_JIT_TYPE_FLOAT
:
1362 case GCC_JIT_TYPE_DOUBLE
:
1363 case GCC_JIT_TYPE_LONG_DOUBLE
:
1366 case GCC_JIT_TYPE_CONST_CHAR_PTR
:
1369 case GCC_JIT_TYPE_SIZE_T
:
1372 case GCC_JIT_TYPE_FILE_PTR
:
1375 case GCC_JIT_TYPE_COMPLEX_FLOAT
:
1376 case GCC_JIT_TYPE_COMPLEX_DOUBLE
:
1377 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE
:
1382 /* Implementation of pure virtual hook recording::type::is_float for
1383 recording::memento_of_get_type. */
1386 recording::memento_of_get_type::is_float () const
1390 default: gcc_unreachable ();
1392 case GCC_JIT_TYPE_VOID
:
1395 case GCC_JIT_TYPE_VOID_PTR
:
1398 case GCC_JIT_TYPE_BOOL
:
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
:
1414 case GCC_JIT_TYPE_FLOAT
:
1415 case GCC_JIT_TYPE_DOUBLE
:
1416 case GCC_JIT_TYPE_LONG_DOUBLE
:
1419 case GCC_JIT_TYPE_CONST_CHAR_PTR
:
1422 case GCC_JIT_TYPE_SIZE_T
:
1425 case GCC_JIT_TYPE_FILE_PTR
:
1428 case GCC_JIT_TYPE_COMPLEX_FLOAT
:
1429 case GCC_JIT_TYPE_COMPLEX_DOUBLE
:
1430 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE
:
1435 /* Implementation of pure virtual hook recording::type::is_bool for
1436 recording::memento_of_get_type. */
1439 recording::memento_of_get_type::is_bool () const
1443 default: gcc_unreachable ();
1445 case GCC_JIT_TYPE_VOID
:
1448 case GCC_JIT_TYPE_VOID_PTR
:
1451 case GCC_JIT_TYPE_BOOL
:
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
:
1467 case GCC_JIT_TYPE_FLOAT
:
1468 case GCC_JIT_TYPE_DOUBLE
:
1469 case GCC_JIT_TYPE_LONG_DOUBLE
:
1472 case GCC_JIT_TYPE_CONST_CHAR_PTR
:
1475 case GCC_JIT_TYPE_SIZE_T
:
1478 case GCC_JIT_TYPE_FILE_PTR
:
1481 case GCC_JIT_TYPE_COMPLEX_FLOAT
:
1482 case GCC_JIT_TYPE_COMPLEX_DOUBLE
:
1483 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE
:
1488 /* Implementation of pure virtual hook recording::memento::replay_into
1489 for recording::memento_of_get_type. */
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. */
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. */
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
)
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. */
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. */
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
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. */
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 ". */
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. */
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 ". */
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. */
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. */
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 (),
1659 /* Implementation of recording::memento::make_debug_string for
1660 results of new_array_type. */
1663 recording::array_type::make_debug_string ()
1665 return string::from_printf (m_ctxt
,
1667 m_element_type
->get_debug_string (),
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
,
1681 m_return_type (return_type
),
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. */
1693 recording::function_type::dereference ()
1698 /* Implementation of pure virtual hook recording::memento::replay_into
1699 for recording::function_type. */
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
;
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 (),
1717 /* Special-casing for make_debug_string for get_pointer results for
1718 handling (one level) of pointers to functions. */
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. */
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
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 */
1754 sz
+= 5; /* ", ..." separator and ellipsis */
1756 /* Now allocate and populate the buffer. */
1757 char *argbuf
= new char[sz
];
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
, ", ");
1772 if (m_param_types
.length ())
1774 strcpy (argbuf
+ len
, ", ");
1777 strcpy (argbuf
+ len
, "...");
1782 /* ...and use it to get the string for the call as a whole. */
1783 string
*result
= string::from_printf (m_ctxt
,
1785 m_return_type
->get_debug_string (),
1794 /* The implementation of class gcc::jit::recording::field. */
1796 /* Implementation of pure virtual hook recording::memento::replay_into
1797 for recording::field. */
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:
1811 so that we can build up a struct/union field-byfield. */
1814 recording::field::write_to_dump (dump
&d
)
1816 d
.write (" %s %s;\n",
1817 m_type
->get_debug_string (),
1821 /* Implementation of recording::memento::make_debug_string for
1822 results of new_field. */
1825 recording::field::make_debug_string ()
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
,
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. */
1851 recording::compound_type::set_fields (location
*loc
,
1853 field
**field_array
)
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. */
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
,
1878 : compound_type (ctxt
, loc
, name
)
1882 /* Implementation of pure virtual hook recording::memento::replay_into
1883 for recording::struct_. */
1886 recording::struct_::replay_into (replayer
*r
)
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
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
,
1911 : compound_type (ctxt
, loc
, name
)
1915 /* Implementation of pure virtual hook recording::memento::replay_into
1916 for recording::union_. */
1919 recording::union_::replay_into (replayer
*r
)
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
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
,
1944 : memento (struct_or_union
->m_ctxt
),
1945 m_struct_or_union (struct_or_union
),
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. */
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:
1983 recording::fields::write_to_dump (dump
&d
)
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
);
1994 /* Implementation of recording::memento::make_debug_string for
1998 recording::fields::make_debug_string ()
2000 return string::from_printf (m_ctxt
,
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. */
2013 recording::rvalue::access_field (recording::location
*loc
,
2016 recording::rvalue
*result
=
2017 new access_field_rvalue (m_ctxt
, loc
, this, field
);
2018 m_ctxt
->record (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. */
2029 recording::rvalue::dereference_field (recording::location
*loc
,
2032 recording::lvalue
*result
=
2033 new dereference_field_rvalue (m_ctxt
, loc
, this, field
);
2034 m_ctxt
->record (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. */
2045 recording::rvalue::dereference (recording::location
*loc
)
2047 recording::lvalue
*result
=
2048 new dereference_rvalue (m_ctxt
, loc
, this);
2049 m_ctxt
->record (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. */
2062 recording::lvalue::access_field (recording::location
*loc
,
2065 recording::lvalue
*result
=
2066 new access_field_of_lvalue (m_ctxt
, loc
, this, field
);
2067 m_ctxt
->record (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. */
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
);
2086 /* The implementation of class gcc::jit::recording::param. */
2088 /* Implementation of pure virtual hook recording::memento::replay_into
2089 for recording::param. */
2092 recording::param::replay_into (replayer
*r
)
2094 set_playback_obj (r
->new_param (playback_location (r
, m_loc
),
2095 m_type
->playback_type (),
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
,
2108 recording::string
*name
,
2110 recording::param
**params
,
2112 enum built_in_function builtin_id
)
2116 m_return_type (return_type
),
2119 m_is_variadic (is_variadic
),
2120 m_builtin_id (builtin_id
),
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. */
2132 recording::function::replay_into (replayer
*r
)
2134 /* Convert m_params to a vec of playback param. */
2135 auto_vec
<playback::param
*> params
;
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
),
2144 m_return_type
->playback_type (),
2151 /* Create a recording::local instance and add it to
2152 the functions's context's list of mementos, and to the function's
2155 Implements the post-error-checking part of
2156 gcc_jit_function_new_local. */
2159 recording::function::new_local (recording::location
*loc
,
2163 local
*result
= new local (this, loc
, type
, new_string (name
));
2164 m_ctxt
->record (result
);
2165 m_locals
.safe_push (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
2173 Implements the post-error-checking part of
2174 gcc_jit_function_new_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
);
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. */
2195 recording::function::write_to_dump (dump
&d
)
2199 default: gcc_unreachable ();
2200 case GCC_JIT_FUNCTION_EXPORTED
:
2201 case GCC_JIT_FUNCTION_IMPORTED
:
2202 d
.write ("extern ");
2204 case GCC_JIT_FUNCTION_INTERNAL
:
2205 d
.write ("static ");
2207 case GCC_JIT_FUNCTION_ALWAYS_INLINE
:
2208 d
.write ("static inline ");
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 ());
2219 recording::param
*param
;
2220 FOR_EACH_VEC_ELT (m_params
, i
, param
)
2225 param
->get_type ()->get_debug_string (),
2226 param
->get_debug_string ());
2229 if (m_kind
== GCC_JIT_FUNCTION_IMPORTED
)
2231 d
.write ("; /* (imported) */\n\n");
2241 FOR_EACH_VEC_ELT (m_locals
, i
, var
)
2242 var
->write_to_dump (d
);
2243 if (m_locals
.length ())
2246 /* Write each block: */
2247 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
2251 b
->write_to_dump (d
);
2258 /* Pre-compilation validation of a function, for those things we can't
2259 check until the context is (supposedly) fully-populated. */
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;
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
);
2306 if (!next2
->m_is_reachable
)
2307 worklist
.safe_push (next2
);
2310 if (!next1
->m_is_reachable
)
2311 worklist
.safe_push (next1
);
2318 /* Now complain about any blocks that haven't been marked. */
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. */
2335 recording::function::dump_to_dot (const char *path
)
2337 FILE *fp
= fopen (path
, "w");
2341 pretty_printer the_pp
;
2342 the_pp
.buffer
->stream
= fp
;
2344 pretty_printer
*pp
= &the_pp
;
2347 "digraph %s {\n", get_debug_string ());
2353 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
2354 b
->dump_to_dot (pp
);
2361 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
2362 b
->dump_edges_to_dot (pp
);
2365 pp_printf (pp
, "}\n");
2370 /* Implementation of recording::memento::make_debug_string for
2374 recording::function::make_debug_string ()
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
2385 Implements the post-error-checking part of
2386 gcc_jit_block_add_eval. */
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
2401 Implements the post-error-checking part of
2402 gcc_jit_block_add_assignment. */
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
2418 Implements the post-error-checking part of
2419 gcc_jit_block_add_assignment_op. */
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
2436 Implements the post-error-checking part of
2437 gcc_jit_block_add_comment. */
2440 recording::block::add_comment (recording::location
*loc
,
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
2452 Implements the post-error-checking part of
2453 gcc_jit_block_end_with_conditional. */
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
2471 Implements the post-error-checking part of
2472 gcc_jit_block_end_with_jump. */
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
2488 Implements the post-error-checking parts of
2489 gcc_jit_block_end_with_return and
2490 gcc_jit_block_end_with_void_return. */
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
2517 recording::block::write_to_dump (dump
&d
)
2519 d
.write ("%s:\n", get_debug_string ());
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. */
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 ());
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 ();
2554 return stmt
->get_loc ();
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];
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];
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
2591 recording::block::get_successor_blocks (block
**next1
, block
**next2
) const
2593 gcc_assert (m_has_been_terminated
);
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. */
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
2615 recording::block::make_debug_string ()
2620 return string::from_printf (m_ctxt
,
2621 "<UNNAMED BLOCK %p>",
2625 /* Dump a block in graphviz form into PP, capturing the block name (if
2626 any) and the statements. */
2629 recording::block::dump_to_dot (pretty_printer
*pp
)
2633 "[shape=record,style=filled,fillcolor=white,label=\"{"),
2635 pp_write_text_to_stream (pp
);
2638 pp_string (pp
, m_name
->c_str ());
2639 pp_string (pp
, ":");
2641 pp_write_text_as_dot_label_to_stream (pp
, true /*for_record*/);
2646 FOR_EACH_VEC_ELT (m_statements
, i
, s
)
2648 pp_string (pp
, s
->get_debug_string ());
2650 pp_write_text_as_dot_label_to_stream (pp
, true /*for_record*/);
2658 /* Dump the out-edges of the block in graphviz form into PP. */
2661 recording::block::dump_edges_to_dot (pretty_printer
*pp
)
2664 int num_succs
= get_successor_blocks (&next
[0], &next
[1]);
2665 for (int i
= 0; i
< num_succs
; i
++)
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. */
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. */
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 (),
2696 /* Implementation of recording::memento::make_debug_string for
2697 rvalue_from_int, rendering it as
2703 recording::memento_of_new_rvalue_from_int::make_debug_string ()
2705 return string::from_printf (m_ctxt
,
2707 m_type
->get_debug_string (),
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. */
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 (),
2723 /* Implementation of recording::memento::make_debug_string for
2724 rvalue_from_double, rendering it as
2730 recording::memento_of_new_rvalue_from_double::make_debug_string ()
2732 return string::from_printf (m_ctxt
,
2734 m_type
->get_debug_string (),
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. */
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 (),
2750 /* Implementation of recording::memento::make_debug_string for
2751 rvalue_from_ptr, rendering it as
2756 Zero is rendered as NULL e.g.
2760 recording::memento_of_new_rvalue_from_ptr::make_debug_string ()
2762 if (m_value
!= NULL
)
2763 return string::from_printf (m_ctxt
,
2765 m_type
->get_debug_string (), m_value
);
2767 return string::from_printf (m_ctxt
,
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. */
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
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. */
2799 recording::unary_op::replay_into (replayer
*r
)
2801 set_playback_obj (r
->new_unary_op (playback_location (r
, m_loc
),
2803 get_type ()->playback_type (),
2804 m_a
->playback_rvalue ()));
2807 /* Implementation of recording::memento::make_debug_string for
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 */
2818 recording::unary_op::make_debug_string ()
2820 return string::from_printf (m_ctxt
,
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. */
2832 recording::binary_op::replay_into (replayer
*r
)
2834 set_playback_obj (r
->new_binary_op (playback_location (r
, m_loc
),
2836 get_type ()->playback_type (),
2837 m_a
->playback_rvalue (),
2838 m_b
->playback_rvalue ()));
2841 /* Implementation of recording::memento::make_debug_string for
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 */
2860 recording::binary_op::make_debug_string ()
2862 return string::from_printf (m_ctxt
,
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
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 */
2885 recording::comparison::make_debug_string ()
2887 return string::from_printf (m_ctxt
,
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. */
2898 recording::comparison::replay_into (replayer
*r
)
2900 set_playback_obj (r
->new_comparison (playback_location (r
, m_loc
),
2902 m_a
->playback_rvalue (),
2903 m_b
->playback_rvalue ()));
2906 /* Implementation of pure virtual hook recording::memento::replay_into
2907 for recording::cast. */
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
2921 recording::cast::make_debug_string ()
2923 return string::from_printf (m_ctxt
,
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
,
2938 : rvalue (ctxt
, loc
, func
->get_return_type ()),
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. */
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 (),
2962 /* Implementation of recording::memento::make_debug_string for
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
];
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
, ", ");
2993 /* ...and use it to get the string for the call as a whole. */
2994 string
*result
= string::from_printf (m_ctxt
,
2996 m_func
->get_debug_string (),
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
,
3013 : rvalue (ctxt
, loc
,
3014 fn_ptr
->get_type ()->dereference ()
3015 ->as_a_function_type ()->get_return_type ()),
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. */
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 (),
3039 /* Implementation of recording::memento::make_debug_string for
3040 calls through function ptrs. */
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
];
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
, ", ");
3070 /* ...and use it to get the string for the call as a whole. */
3071 string
*result
= string::from_printf (m_ctxt
,
3073 m_fn_ptr
->get_debug_string (),
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. */
3087 recording::array_access::replay_into (replayer
*r
)
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
3099 recording::array_access::make_debug_string ()
3101 return string::from_printf (m_ctxt
,
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. */
3113 recording::access_field_of_lvalue::replay_into (replayer
*r
)
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. */
3126 recording::access_field_of_lvalue::make_debug_string ()
3128 return string::from_printf (m_ctxt
,
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. */
3140 recording::access_field_rvalue::replay_into (replayer
*r
)
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. */
3152 recording::access_field_rvalue::make_debug_string ()
3154 return string::from_printf (m_ctxt
,
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. */
3167 recording::dereference_field_rvalue::replay_into (replayer
*r
)
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. */
3179 recording::dereference_field_rvalue::make_debug_string ()
3181 return string::from_printf (m_ctxt
,
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. */
3193 recording::dereference_rvalue::replay_into (replayer
*r
)
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. */
3204 recording::dereference_rvalue::make_debug_string ()
3206 return string::from_printf (m_ctxt
,
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. */
3217 recording::get_address_of_lvalue::replay_into (replayer
*r
)
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. */
3228 recording::get_address_of_lvalue::make_debug_string ()
3230 return string::from_printf (m_ctxt
,
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. */
3241 recording::local::replay_into (replayer
*r
)
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
3253 for use at the top of the function body as if it were a
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
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. */
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
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. */
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. */
3313 recording::eval::make_debug_string ()
3315 return string::from_printf (m_ctxt
,
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. */
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. */
3338 recording::assignment::make_debug_string ()
3340 return string::from_printf (m_ctxt
,
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. */
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
),
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 (),
3370 /* Implementation of recording::memento::make_debug_string for
3371 an assignment_op statement. */
3374 recording::assignment_op::make_debug_string ()
3376 return string::from_printf (m_ctxt
,
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. */
3389 recording::comment::replay_into (replayer
*r
)
3391 playback_block (get_block ())
3392 ->add_comment (playback_location (r
),
3396 /* Implementation of recording::memento::make_debug_string for
3397 a comment "statement". */
3400 recording::comment::make_debug_string ()
3402 return string::from_printf (m_ctxt
,
3407 /* The implementation of class gcc::jit::recording::conditional. */
3409 /* Implementation of pure virtual hook recording::memento::replay_into
3410 for recording::conditional. */
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
;
3436 /* Implementation of recording::memento::make_debug_string for
3437 a conditional jump statement. */
3440 recording::conditional::make_debug_string ()
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 ());
3449 return string::from_printf (m_ctxt
,
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. */
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
;
3481 /* Implementation of recording::memento::make_debug_string for
3482 a unconditional jump statement. */
3485 recording::jump::make_debug_string ()
3487 return string::from_printf (m_ctxt
,
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_. */
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
3517 /* Implementation of recording::memento::make_debug_string for
3518 a return statement (covers both those with and without rvalues). */
3521 recording::return_::make_debug_string ()
3524 return string::from_printf (m_ctxt
,
3526 m_rvalue
->get_debug_string ());
3528 return string::from_printf (m_ctxt
,
3532 } // namespace gcc::jit