1 /* Internals of libgccjit: classes for recording calls made to the JIT API.
2 Copyright (C) 2013-2014 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
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-recording.h"
34 #include "jit-playback.h"
41 dump::dump (recording::context
&ctxt
,
43 bool update_locations
)
45 m_filename (filename
),
46 m_update_locations (update_locations
),
50 m_file
= fopen (filename
, "w");
53 "error opening dump file %s for writing: %s",
62 int err
= fclose (m_file
);
64 m_ctxt
.add_error (NULL
,
65 "error closing dump file %s: %s",
71 /* Write the given message to the dump, using printf-formatting
72 conventions, updating the line/column within the dump.
74 Emit an error on the context if a failure occurs. */
77 dump::write (const char *fmt
, ...)
82 /* If there was an error opening the file, we've already reported it.
83 Don't attempt further work. */
88 vasprintf (&buf
, fmt
, ap
);
93 m_ctxt
.add_error (NULL
, "malloc failure writing to dumpfile %s",
98 if (fwrite (buf
, strlen (buf
), 1, m_file
) != 1)
99 m_ctxt
.add_error (NULL
, "error writing to dump file %s",
102 /* Update line/column: */
103 for (const char *ptr
= buf
; *ptr
; ptr
++)
117 /* Construct a gcc::jit::recording::location instance for the current
118 location within the dump. */
120 recording::location
*
121 dump::make_location () const
123 return m_ctxt
.new_location (m_filename
, m_line
, m_column
);
126 /**********************************************************************
128 **********************************************************************/
130 /* Get the playback::location for the given recording::location,
131 handling a NULL input with a NULL output. */
134 recording::playback_location (replayer
*r
, recording::location
*loc
)
137 return loc
->playback_location (r
);
142 /* Get a const char * for the given recording::string
143 handling a NULL input with a NULL output. */
146 recording::playback_string (recording::string
*str
)
149 return str
->c_str ();
154 /* Get the playback::block for the given recording::block,
155 handling a NULL input with a NULL output. */
158 recording::playback_block (recording::block
*b
)
161 return b
->playback_block ();
166 /* Methods of cc::jit::recording::context. */
168 /* The constructor for gcc::jit::recording::context, used by
169 gcc_jit_context_acquire and gcc_jit_context_new_child_context. */
171 recording::context::context (context
*parent_ctxt
)
172 : m_parent_ctxt (parent_ctxt
),
174 m_first_error_str (NULL
),
175 m_owns_first_error_str (false),
180 m_builtins_manager(NULL
)
184 /* Inherit options from parent.
185 Note that the first memcpy means copying pointers to strings. */
186 memcpy (m_str_options
,
187 parent_ctxt
->m_str_options
,
188 sizeof (m_str_options
));
189 memcpy (m_int_options
,
190 parent_ctxt
->m_int_options
,
191 sizeof (m_int_options
));
192 memcpy (m_bool_options
,
193 parent_ctxt
->m_bool_options
,
194 sizeof (m_bool_options
));
198 memset (m_str_options
, 0, sizeof (m_str_options
));
199 memset (m_int_options
, 0, sizeof (m_int_options
));
200 memset (m_bool_options
, 0, sizeof (m_bool_options
));
203 memset (m_basic_types
, 0, sizeof (m_basic_types
));
206 /* The destructor for gcc::jit::recording::context, implicitly used by
207 gcc_jit_context_release. */
209 recording::context::~context ()
213 FOR_EACH_VEC_ELT (m_mementos
, i
, m
)
218 for (i
= 0; i
< GCC_JIT_NUM_STR_OPTIONS
; ++i
)
219 free (m_str_options
[i
]);
221 if (m_builtins_manager
)
222 delete m_builtins_manager
;
224 if (m_owns_first_error_str
)
225 free (m_first_error_str
);
228 /* Add the given mememto to the list of those tracked by this
229 gcc::jit::recording::context, so that e.g. it can be deleted
230 when this context is released. */
233 recording::context::record (memento
*m
)
237 m_mementos
.safe_push (m
);
240 /* Replay this context (and any parents) into the given replayer. */
243 recording::context::replay_into (replayer
*r
)
248 /* If we have a parent context, we must replay it. This will
249 recursively walk backwards up the historical tree, then replay things
250 forwards "in historical order", starting with the ultimate parent
251 context, until we reach the "this" context.
253 Note that we fully replay the parent, then fully replay the child,
254 which means that inter-context references can only exist from child
255 to parent, not the other way around.
257 All of this replaying is suboptimal - it would be better to do the
258 work for the parent context *once*, rather than replaying the parent
259 every time we replay each child. However, fixing this requires deep
260 surgery to lifetime-management: we'd need every context family tree
261 to have its own GC heap, and to initialize the GCC code to use that
262 heap (with a mutex on such a heap). */
264 m_parent_ctxt
->replay_into (r
);
266 if (r
->errors_occurred ())
269 /* Replay this context's saved operations into r. */
270 FOR_EACH_VEC_ELT (m_mementos
, i
, m
)
272 /* Disabled low-level debugging, here if we need it: print what
274 Note that the calls to get_debug_string might lead to more
275 mementos being created for the strings.
276 This can also be used to exercise the debug_string
279 printf ("context %p replaying (%p): %s\n",
280 (void *)this, (void *)m
, m
->get_debug_string ());
284 if (r
->errors_occurred ())
289 /* During a playback, we associate objects from the recording with
290 their counterparts during this playback.
292 For simplicity, we store this within the recording objects.
294 The following method cleans away these associations, to ensure that
295 we never have out-of-date associations lingering on subsequent
296 playbacks (the objects pointed to are GC-managed, but the
297 recording objects don't own refs to them). */
300 recording::context::disassociate_from_playback ()
306 m_parent_ctxt
->disassociate_from_playback ();
308 FOR_EACH_VEC_ELT (m_mementos
, i
, m
)
310 m
->set_playback_obj (NULL
);
314 /* Create a recording::string instance and add it to this context's list
317 This creates a fresh copy of the given 0-terminated buffer. */
320 recording::context::new_string (const char *text
)
325 recording::string
*result
= new string (this, text
);
330 /* Create a recording::location instance and add it to this context's
333 Implements the post-error-checking part of
334 gcc_jit_context_new_location. */
336 recording::location
*
337 recording::context::new_location (const char *filename
,
341 recording::location
*result
=
342 new recording::location (this,
343 new_string (filename
),
349 /* If we haven't seen this enum value yet, create a recording::type
350 instance and add it to this context's list of mementos.
352 If we have seen it before, reuse our cached value, so that repeated
353 calls on the context give the same object.
355 If we have a parent context, the cache is within the ultimate
358 Implements the post-error-checking part of
359 gcc_jit_context_get_type. */
362 recording::context::get_type (enum gcc_jit_types kind
)
364 if (!m_basic_types
[kind
])
367 m_basic_types
[kind
] = m_parent_ctxt
->get_type (kind
);
370 recording::type
*result
= new memento_of_get_type (this, kind
);
372 m_basic_types
[kind
] = result
;
376 return m_basic_types
[kind
];
379 /* Get a recording::type instance for the given size and signedness.
380 This is implemented in terms of recording::context::get_type
383 Implements the post-error-checking part of
384 gcc_jit_context_get_int_type. */
387 recording::context::get_int_type (int num_bytes
, int is_signed
)
389 /* We can't use a switch here since some of the values are macros affected
390 by options; e.g. i386.h has
391 #define LONG_TYPE_SIZE (TARGET_X32 ? 32 : BITS_PER_WORD)
392 Compare with tree.c's make_or_reuse_type. Note that the _SIZE macros
393 are in bits, rather than bytes.
395 const int num_bits
= num_bytes
* 8;
396 if (num_bits
== INT_TYPE_SIZE
)
397 return get_type (is_signed
399 : GCC_JIT_TYPE_UNSIGNED_INT
);
400 if (num_bits
== CHAR_TYPE_SIZE
)
401 return get_type (is_signed
402 ? GCC_JIT_TYPE_SIGNED_CHAR
403 : GCC_JIT_TYPE_UNSIGNED_CHAR
);
404 if (num_bits
== SHORT_TYPE_SIZE
)
405 return get_type (is_signed
407 : GCC_JIT_TYPE_UNSIGNED_SHORT
);
408 if (num_bits
== LONG_TYPE_SIZE
)
409 return get_type (is_signed
411 : GCC_JIT_TYPE_UNSIGNED_LONG
);
412 if (num_bits
== LONG_LONG_TYPE_SIZE
)
413 return get_type (is_signed
414 ? GCC_JIT_TYPE_LONG_LONG
415 : GCC_JIT_TYPE_UNSIGNED_LONG_LONG
);
417 /* Some other size, not corresponding to the C int types. */
418 /* To be written: support arbitrary other sizes, sharing by
419 memoizing at the recording::context level? */
423 /* Create a recording::type instance and add it to this context's list
426 Implements the post-error-checking part of
427 gcc_jit_context_new_array_type. */
430 recording::context::new_array_type (recording::location
*loc
,
431 recording::type
*element_type
,
434 if (struct_
*s
= element_type
->dyn_cast_struct ())
435 if (!s
->get_fields ())
438 "cannot create an array of type %s"
439 " until the fields have been set",
440 s
->get_name ()->c_str ());
443 recording::type
*result
=
444 new recording::array_type (this, loc
, element_type
, num_elements
);
449 /* Create a recording::field instance and add it to this context's list
452 Implements the post-error-checking part of
453 gcc_jit_context_new_field. */
456 recording::context::new_field (recording::location
*loc
,
457 recording::type
*type
,
460 recording::field
*result
=
461 new recording::field (this, loc
, type
, new_string (name
));
466 /* Create a recording::struct_ instance and add it to this context's
467 list of mementos and list of compound types.
469 Implements the post-error-checking part of
470 gcc_jit_context_new_struct_type. */
473 recording::context::new_struct_type (recording::location
*loc
,
476 recording::struct_
*result
= new struct_ (this, loc
, new_string (name
));
478 m_compound_types
.safe_push (result
);
482 /* Create a recording::union_ instance and add it to this context's
483 list of mementos and list of compound types.
485 Implements the first post-error-checking part of
486 gcc_jit_context_new_union_type. */
489 recording::context::new_union_type (recording::location
*loc
,
492 recording::union_
*result
= new union_ (this, loc
, new_string (name
));
494 m_compound_types
.safe_push (result
);
498 /* Create a recording::function_type instance and add it to this context's
501 Used by new_function_ptr_type and by builtins_manager::make_fn_type. */
503 recording::function_type
*
504 recording::context::new_function_type (recording::type
*return_type
,
506 recording::type
**param_types
,
509 recording::function_type
*fn_type
510 = new function_type (this,
519 /* Create a recording::type instance and add it to this context's list
522 Implements the post-error-checking part of
523 gcc_jit_context_new_function_ptr_type. */
526 recording::context::new_function_ptr_type (recording::location
*, /* unused loc */
527 recording::type
*return_type
,
529 recording::type
**param_types
,
532 recording::function_type
*fn_type
533 = new_function_type (return_type
,
538 /* Return a pointer-type to the the function type. */
539 return fn_type
->get_pointer ();
542 /* Create a recording::param instance and add it to this context's list
545 Implements the post-error-checking part of
546 gcc_jit_context_new_param. */
549 recording::context::new_param (recording::location
*loc
,
550 recording::type
*type
,
553 recording::param
*result
= new recording::param (this, loc
, type
, new_string (name
));
558 /* Create a recording::function instance and add it to this context's list
559 of mementos and list of functions.
561 Implements the post-error-checking part of
562 gcc_jit_context_new_function. */
564 recording::function
*
565 recording::context::new_function (recording::location
*loc
,
566 enum gcc_jit_function_kind kind
,
567 recording::type
*return_type
,
570 recording::param
**params
,
572 enum built_in_function builtin_id
)
574 recording::function
*result
=
575 new recording::function (this,
576 loc
, kind
, return_type
,
578 num_params
, params
, is_variadic
,
581 m_functions
.safe_push (result
);
586 /* Locate the builtins_manager (if any) for this family of contexts,
587 creating it if it doesn't exist already.
589 All of the recording contexts in a family share one builtins_manager:
590 if we have a child context, follow the parent links to get the
591 ultimate ancestor context, and look for it/store it there. */
594 recording::context::get_builtins_manager ()
597 return m_parent_ctxt
->get_builtins_manager ();
599 if (!m_builtins_manager
)
600 m_builtins_manager
= new builtins_manager (this);
602 return m_builtins_manager
;
605 /* Get a recording::function instance, which is lazily-created and added
606 to the context's lists of mementos.
608 Implements the post-error-checking part of
609 gcc_jit_context_get_builtin_function. */
611 recording::function
*
612 recording::context::get_builtin_function (const char *name
)
614 builtins_manager
*bm
= get_builtins_manager ();
615 return bm
->get_builtin_function (name
);
618 /* Create a recording::global instance and add it to this context's list
621 Implements the post-error-checking part of
622 gcc_jit_context_new_global. */
625 recording::context::new_global (recording::location
*loc
,
626 recording::type
*type
,
629 recording::lvalue
*result
=
630 new recording::global (this, loc
, type
, new_string (name
));
635 /* Create a recording::memento_of_new_rvalue_from_int instance and add
636 it to this context's list of mementos.
638 Implements the post-error-checking part of
639 gcc_jit_context_new_rvalue_from_int. */
642 recording::context::new_rvalue_from_int (recording::type
*type
,
645 recording::rvalue
*result
=
646 new memento_of_new_rvalue_from_int (this, NULL
, type
, value
);
651 /* Create a recording::memento_of_new_rvalue_from_double instance and
652 add it to this context's list of mementos.
654 Implements the post-error-checking part of
655 gcc_jit_context_new_rvalue_from_double. */
658 recording::context::new_rvalue_from_double (recording::type
*type
,
661 recording::rvalue
*result
=
662 new memento_of_new_rvalue_from_double (this, NULL
, type
, value
);
667 /* Create a recording::memento_of_new_rvalue_from_ptr instance and add
668 it to this context's list of mementos.
670 Implements the post-error-checking part of
671 gcc_jit_context_new_rvalue_from_ptr. */
674 recording::context::new_rvalue_from_ptr (recording::type
*type
,
677 recording::rvalue
*result
=
678 new memento_of_new_rvalue_from_ptr (this, NULL
, type
, value
);
683 /* Create a recording::memento_of_new_string_literal instance and add it
684 to this context's list of mementos.
686 Implements the post-error-checking part of
687 gcc_jit_context_new_string_literal. */
690 recording::context::new_string_literal (const char *value
)
692 recording::rvalue
*result
=
693 new memento_of_new_string_literal (this, NULL
, new_string (value
));
698 /* Create a recording::unary_op instance and add it to this context's
701 Implements the post-error-checking part of
702 gcc_jit_context_new_unary_op. */
705 recording::context::new_unary_op (recording::location
*loc
,
706 enum gcc_jit_unary_op op
,
707 recording::type
*result_type
,
708 recording::rvalue
*a
)
710 recording::rvalue
*result
=
711 new unary_op (this, loc
, op
, result_type
, a
);
716 /* Create a recording::binary_op instance and add it to this context's
719 Implements the post-error-checking part of
720 gcc_jit_context_new_binary_op. */
723 recording::context::new_binary_op (recording::location
*loc
,
724 enum gcc_jit_binary_op op
,
725 recording::type
*result_type
,
726 recording::rvalue
*a
,
727 recording::rvalue
*b
)
729 recording::rvalue
*result
=
730 new binary_op (this, loc
, op
, result_type
, a
, b
);
735 /* Create a recording::comparison instance and add it to this context's
738 Implements the post-error-checking part of
739 gcc_jit_context_new_comparison. */
742 recording::context::new_comparison (recording::location
*loc
,
743 enum gcc_jit_comparison op
,
744 recording::rvalue
*a
,
745 recording::rvalue
*b
)
747 recording::rvalue
*result
= new comparison (this, loc
, op
, a
, b
);
752 /* Create a recording::cast instance and add it to this context's list
755 Implements the post-error-checking part of
756 gcc_jit_context_new_cast. */
759 recording::context::new_cast (recording::location
*loc
,
760 recording::rvalue
*expr
,
761 recording::type
*type_
)
763 recording::rvalue
*result
= new cast (this, loc
, expr
, type_
);
768 /* Create a recording::call instance and add it to this context's list
771 Implements the post-error-checking part of
772 gcc_jit_context_new_call. */
775 recording::context::new_call (recording::location
*loc
,
777 int numargs
, recording::rvalue
**args
)
779 recording::rvalue
*result
= new call (this, loc
, func
, numargs
, args
);
784 /* Create a recording::call_through_ptr instance and add it to this
785 context's list of mementos.
787 Implements the post-error-checking part of
788 gcc_jit_context_new_call_through_ptr. */
791 recording::context::new_call_through_ptr (recording::location
*loc
,
792 recording::rvalue
*fn_ptr
,
794 recording::rvalue
**args
)
796 recording::rvalue
*result
= new call_through_ptr (this, loc
, fn_ptr
, numargs
, args
);
801 /* Create a recording::array_access instance and add it to this context's list
804 Implements the post-error-checking part of
805 gcc_jit_context_new_array_access. */
808 recording::context::new_array_access (recording::location
*loc
,
809 recording::rvalue
*ptr
,
810 recording::rvalue
*index
)
812 recording::lvalue
*result
= new array_access (this, loc
, ptr
, index
);
817 /* Set the given string option for this context, or add an error if
820 Implements the post-error-checking part of
821 gcc_jit_context_set_str_option. */
824 recording::context::set_str_option (enum gcc_jit_str_option opt
,
827 if (opt
< 0 || opt
>= GCC_JIT_NUM_STR_OPTIONS
)
830 "unrecognized (enum gcc_jit_str_option) value: %i", opt
);
833 free (m_str_options
[opt
]);
834 m_str_options
[opt
] = xstrdup (value
);
837 /* Set the given integer option for this context, or add an error if
840 Implements the post-error-checking part of
841 gcc_jit_context_set_int_option. */
844 recording::context::set_int_option (enum gcc_jit_int_option opt
,
847 if (opt
< 0 || opt
>= GCC_JIT_NUM_INT_OPTIONS
)
850 "unrecognized (enum gcc_jit_int_option) value: %i", opt
);
853 m_int_options
[opt
] = value
;
856 /* Set the given boolean option for this context, or add an error if
859 Implements the post-error-checking part of
860 gcc_jit_context_set_bool_option. */
863 recording::context::set_bool_option (enum gcc_jit_bool_option opt
,
866 if (opt
< 0 || opt
>= GCC_JIT_NUM_BOOL_OPTIONS
)
869 "unrecognized (enum gcc_jit_bool_option) value: %i", opt
);
872 m_bool_options
[opt
] = value
? true : false;
875 /* Add the given dumpname/out_ptr pair to this context's list of requested
878 Implements the post-error-checking part of
879 gcc_jit_context_enable_dump. */
882 recording::context::enable_dump (const char *dumpname
,
886 gcc_assert (dumpname
);
887 gcc_assert (out_ptr
);
889 d
.m_dumpname
= dumpname
;
890 d
.m_out_ptr
= out_ptr
;
892 m_requested_dumps
.safe_push (d
);
895 /* Validate this context, and if it passes, compile it within a
898 Implements the post-error-checking part of
899 gcc_jit_context_compile. */
902 recording::context::compile ()
906 if (errors_occurred ())
909 /* Set up a playback context. */
910 ::gcc::jit::playback::context
replayer (this);
913 result
*result_obj
= replayer
.compile ();
918 /* Format the given error using printf's conventions, print
919 it to stderr, and add it to the context. */
922 recording::context::add_error (location
*loc
, const char *fmt
, ...)
926 add_error_va (loc
, fmt
, ap
);
930 /* Format the given error using printf's conventions, print
931 it to stderr, and add it to the context. */
934 recording::context::add_error_va (location
*loc
, const char *fmt
, va_list ap
)
940 vasprintf (&malloced_msg
, fmt
, ap
);
943 errmsg
= malloced_msg
;
944 has_ownership
= true;
948 errmsg
= "out of memory generating error message";
949 has_ownership
= false;
952 const char *ctxt_progname
=
953 get_str_option (GCC_JIT_STR_OPTION_PROGNAME
);
955 ctxt_progname
= "libgccjit.so";
958 fprintf (stderr
, "%s: %s: error: %s\n",
960 loc
->get_debug_string (),
963 fprintf (stderr
, "%s: error: %s\n",
969 m_first_error_str
= const_cast <char *> (errmsg
);
970 m_owns_first_error_str
= has_ownership
;
979 /* Get the message for the first error that occurred on this context, or
980 NULL if no errors have occurred on it.
982 Implements the post-error-checking part of
983 gcc_jit_context_get_first_error. */
986 recording::context::get_first_error () const
988 return m_first_error_str
;
991 /* Lazily generate and record a recording::type representing an opaque
994 For use if client code tries to dereference the result of
995 get_type (GCC_JIT_TYPE_FILE_PTR). */
998 recording::context::get_opaque_FILE_type ()
1001 m_FILE_type
= new_struct_type (NULL
, "FILE");
1005 /* Dump a C-like representation of the given context to the given path.
1006 If UPDATE_LOCATIONS is true, update the locations within the
1007 context's mementos to point to the dumpfile.
1009 Implements the post-error-checking part of
1010 gcc_jit_context_dump_to_file. */
1013 recording::context::dump_to_file (const char *path
, bool update_locations
)
1016 dump
d (*this, path
, update_locations
);
1018 /* Forward declaration of structs and unions. */
1020 FOR_EACH_VEC_ELT (m_compound_types
, i
, st
)
1022 d
.write ("%s;\n\n", st
->get_debug_string ());
1025 /* Content of structs, where set. */
1026 FOR_EACH_VEC_ELT (m_compound_types
, i
, st
)
1027 if (st
->get_fields ())
1029 st
->get_fields ()->write_to_dump (d
);
1034 FOR_EACH_VEC_ELT (m_functions
, i
, fn
)
1036 fn
->write_to_dump (d
);
1040 /* Copy the requested dumps within this context and all ancestors into
1044 recording::context::get_all_requested_dumps (vec
<recording::requested_dump
> *out
)
1047 m_parent_ctxt
->get_all_requested_dumps (out
);
1049 out
->reserve (m_requested_dumps
.length ());
1050 out
->splice (m_requested_dumps
);
1053 /* This is a pre-compilation check for the context (and any parents).
1055 Detect errors within the context, adding errors if any are found. */
1058 recording::context::validate ()
1061 m_parent_ctxt
->validate ();
1065 FOR_EACH_VEC_ELT (m_functions
, i
, fn
)
1069 /* The implementation of class gcc::jit::recording::memento. */
1071 /* Get a (const char *) debug description of the given memento, by
1072 calling the pure-virtual make_debug_string hook, caching the
1075 It is intended that this should only be called in debugging and
1076 error-handling paths, so this doesn't need to be particularly
1080 recording::memento::get_debug_string ()
1082 if (!m_debug_string
)
1083 m_debug_string
= make_debug_string ();
1084 return m_debug_string
->c_str ();
1087 /* Default implementation of recording::memento::write_to_dump, writing
1088 an indented form of the memento's debug string to the dump. */
1091 recording::memento::write_to_dump (dump
&d
)
1093 d
.write(" %s\n", get_debug_string ());
1096 /* The implementation of class gcc::jit::recording::string. */
1098 /* Constructor for gcc::jit::recording::string::string, allocating a
1099 copy of the given text using new char[]. */
1101 recording::string::string (context
*ctxt
, const char *text
)
1104 m_len
= strlen (text
);
1105 m_buffer
= new char[m_len
+ 1];
1106 strcpy (m_buffer
, text
);
1109 /* Destructor for gcc::jit::recording::string::string. */
1111 recording::string::~string ()
1116 /* Function for making gcc::jit::recording::string instances on a
1117 context via printf-style formatting.
1119 It is intended that this should only be called in debugging and
1120 error-handling paths, so this doesn't need to be particularly
1121 optimized, hence the double-copy of the string is acceptable. */
1124 recording::string::from_printf (context
*ctxt
, const char *fmt
, ...)
1128 recording::string
*result
;
1131 vasprintf (&buf
, fmt
, ap
);
1136 ctxt
->add_error (NULL
, "malloc failure");
1140 result
= ctxt
->new_string (buf
);
1145 /* Implementation of recording::memento::make_debug_string for strings,
1146 wrapping the given string in quotes and escaping as necessary. */
1149 recording::string::make_debug_string ()
1151 /* Hack to avoid infinite recursion into strings when logging all
1152 mementos: don't re-escape strings: */
1153 if (m_buffer
[0] == '"')
1156 /* Wrap in quotes and do escaping etc */
1158 size_t sz
= (1 /* opening quote */
1159 + (m_len
* 2) /* each char might get escaped */
1160 + 1 /* closing quote */
1161 + 1); /* nil termintator */
1162 char *tmp
= new char[sz
];
1165 #define APPEND(CH) do { gcc_assert (len < sz); tmp[len++] = (CH); } while (0)
1166 APPEND('"'); /* opening quote */
1167 for (size_t i
= 0; i
< m_len
; i
++)
1169 char ch
= m_buffer
[i
];
1170 if (ch
== '\t' || ch
== '\n' || ch
== '\\' || ch
== '"')
1174 APPEND('"'); /* closing quote */
1176 tmp
[len
] = '\0'; /* nil termintator */
1178 string
*result
= m_ctxt
->new_string (tmp
);
1184 /* The implementation of class gcc::jit::recording::location. */
1186 /* Implementation of recording::memento::replay_into for locations.
1188 Create a new playback::location and store it into the
1189 recording::location's m_playback_obj field. */
1192 recording::location::replay_into (replayer
*r
)
1194 m_playback_obj
= r
->new_location (this,
1195 m_filename
->c_str (),
1200 /* Implementation of recording::memento::make_debug_string for locations,
1201 turning them into the usual form:
1202 FILENAME:LINE:COLUMN
1203 like we do when emitting diagnostics. */
1206 recording::location::make_debug_string ()
1208 return string::from_printf (m_ctxt
,
1210 m_filename
->c_str (), m_line
, m_column
);
1213 /* The implementation of class gcc::jit::recording::type. */
1215 /* Given a type T, get the type T*.
1217 If this doesn't already exist, generate a new memento_of_get_pointer
1218 instance and add it to this type's context's list of mementos.
1220 Otherwise, use the cached type.
1222 Implements the post-error-checking part of
1223 gcc_jit_type_get_pointer. */
1226 recording::type::get_pointer ()
1228 if (!m_pointer_to_this_type
)
1230 m_pointer_to_this_type
= new memento_of_get_pointer (this);
1231 m_ctxt
->record (m_pointer_to_this_type
);
1233 return m_pointer_to_this_type
;
1236 /* Given a type T, get the type const T.
1238 Implements the post-error-checking part of
1239 gcc_jit_type_get_const. */
1242 recording::type::get_const ()
1244 recording::type
*result
= new memento_of_get_const (this);
1245 m_ctxt
->record (result
);
1249 /* Given a type T, get the type volatile T.
1251 Implements the post-error-checking part of
1252 gcc_jit_type_get_volatile. */
1255 recording::type::get_volatile ()
1257 recording::type
*result
= new memento_of_get_volatile (this);
1258 m_ctxt
->record (result
);
1262 /* Implementation of pure virtual hook recording::type::dereference for
1263 recording::memento_of_get_type. */
1266 recording::memento_of_get_type::dereference ()
1270 default: gcc_unreachable ();
1272 case GCC_JIT_TYPE_VOID
:
1275 case GCC_JIT_TYPE_VOID_PTR
:
1276 return m_ctxt
->get_type (GCC_JIT_TYPE_VOID
);
1278 case GCC_JIT_TYPE_BOOL
:
1279 case GCC_JIT_TYPE_CHAR
:
1280 case GCC_JIT_TYPE_SIGNED_CHAR
:
1281 case GCC_JIT_TYPE_UNSIGNED_CHAR
:
1282 case GCC_JIT_TYPE_SHORT
:
1283 case GCC_JIT_TYPE_UNSIGNED_SHORT
:
1284 case GCC_JIT_TYPE_INT
:
1285 case GCC_JIT_TYPE_UNSIGNED_INT
:
1286 case GCC_JIT_TYPE_LONG
:
1287 case GCC_JIT_TYPE_UNSIGNED_LONG
:
1288 case GCC_JIT_TYPE_LONG_LONG
:
1289 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG
:
1290 case GCC_JIT_TYPE_FLOAT
:
1291 case GCC_JIT_TYPE_DOUBLE
:
1292 case GCC_JIT_TYPE_LONG_DOUBLE
:
1293 case GCC_JIT_TYPE_COMPLEX_FLOAT
:
1294 case GCC_JIT_TYPE_COMPLEX_DOUBLE
:
1295 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE
:
1296 /* Not a pointer: */
1299 case GCC_JIT_TYPE_CONST_CHAR_PTR
:
1300 return m_ctxt
->get_type (GCC_JIT_TYPE_CHAR
)->get_const ();
1302 case GCC_JIT_TYPE_SIZE_T
:
1303 /* Not a pointer: */
1306 case GCC_JIT_TYPE_FILE_PTR
:
1307 /* Give the client code back an opaque "struct FILE". */
1308 return m_ctxt
->get_opaque_FILE_type ();
1312 /* Implementation of pure virtual hook recording::type::is_int for
1313 recording::memento_of_get_type. */
1316 recording::memento_of_get_type::is_int () const
1320 default: gcc_unreachable ();
1322 case GCC_JIT_TYPE_VOID
:
1325 case GCC_JIT_TYPE_VOID_PTR
:
1328 case GCC_JIT_TYPE_BOOL
:
1331 case GCC_JIT_TYPE_CHAR
:
1332 case GCC_JIT_TYPE_SIGNED_CHAR
:
1333 case GCC_JIT_TYPE_UNSIGNED_CHAR
:
1334 case GCC_JIT_TYPE_SHORT
:
1335 case GCC_JIT_TYPE_UNSIGNED_SHORT
:
1336 case GCC_JIT_TYPE_INT
:
1337 case GCC_JIT_TYPE_UNSIGNED_INT
:
1338 case GCC_JIT_TYPE_LONG
:
1339 case GCC_JIT_TYPE_UNSIGNED_LONG
:
1340 case GCC_JIT_TYPE_LONG_LONG
:
1341 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG
:
1344 case GCC_JIT_TYPE_FLOAT
:
1345 case GCC_JIT_TYPE_DOUBLE
:
1346 case GCC_JIT_TYPE_LONG_DOUBLE
:
1349 case GCC_JIT_TYPE_CONST_CHAR_PTR
:
1352 case GCC_JIT_TYPE_SIZE_T
:
1355 case GCC_JIT_TYPE_FILE_PTR
:
1358 case GCC_JIT_TYPE_COMPLEX_FLOAT
:
1359 case GCC_JIT_TYPE_COMPLEX_DOUBLE
:
1360 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE
:
1365 /* Implementation of pure virtual hook recording::type::is_float for
1366 recording::memento_of_get_type. */
1369 recording::memento_of_get_type::is_float () const
1373 default: gcc_unreachable ();
1375 case GCC_JIT_TYPE_VOID
:
1378 case GCC_JIT_TYPE_VOID_PTR
:
1381 case GCC_JIT_TYPE_BOOL
:
1384 case GCC_JIT_TYPE_CHAR
:
1385 case GCC_JIT_TYPE_SIGNED_CHAR
:
1386 case GCC_JIT_TYPE_UNSIGNED_CHAR
:
1387 case GCC_JIT_TYPE_SHORT
:
1388 case GCC_JIT_TYPE_UNSIGNED_SHORT
:
1389 case GCC_JIT_TYPE_INT
:
1390 case GCC_JIT_TYPE_UNSIGNED_INT
:
1391 case GCC_JIT_TYPE_LONG
:
1392 case GCC_JIT_TYPE_UNSIGNED_LONG
:
1393 case GCC_JIT_TYPE_LONG_LONG
:
1394 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG
:
1397 case GCC_JIT_TYPE_FLOAT
:
1398 case GCC_JIT_TYPE_DOUBLE
:
1399 case GCC_JIT_TYPE_LONG_DOUBLE
:
1402 case GCC_JIT_TYPE_CONST_CHAR_PTR
:
1405 case GCC_JIT_TYPE_SIZE_T
:
1408 case GCC_JIT_TYPE_FILE_PTR
:
1411 case GCC_JIT_TYPE_COMPLEX_FLOAT
:
1412 case GCC_JIT_TYPE_COMPLEX_DOUBLE
:
1413 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE
:
1418 /* Implementation of pure virtual hook recording::type::is_bool for
1419 recording::memento_of_get_type. */
1422 recording::memento_of_get_type::is_bool () const
1426 default: gcc_unreachable ();
1428 case GCC_JIT_TYPE_VOID
:
1431 case GCC_JIT_TYPE_VOID_PTR
:
1434 case GCC_JIT_TYPE_BOOL
:
1437 case GCC_JIT_TYPE_CHAR
:
1438 case GCC_JIT_TYPE_SIGNED_CHAR
:
1439 case GCC_JIT_TYPE_UNSIGNED_CHAR
:
1440 case GCC_JIT_TYPE_SHORT
:
1441 case GCC_JIT_TYPE_UNSIGNED_SHORT
:
1442 case GCC_JIT_TYPE_INT
:
1443 case GCC_JIT_TYPE_UNSIGNED_INT
:
1444 case GCC_JIT_TYPE_LONG
:
1445 case GCC_JIT_TYPE_UNSIGNED_LONG
:
1446 case GCC_JIT_TYPE_LONG_LONG
:
1447 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG
:
1450 case GCC_JIT_TYPE_FLOAT
:
1451 case GCC_JIT_TYPE_DOUBLE
:
1452 case GCC_JIT_TYPE_LONG_DOUBLE
:
1455 case GCC_JIT_TYPE_CONST_CHAR_PTR
:
1458 case GCC_JIT_TYPE_SIZE_T
:
1461 case GCC_JIT_TYPE_FILE_PTR
:
1464 case GCC_JIT_TYPE_COMPLEX_FLOAT
:
1465 case GCC_JIT_TYPE_COMPLEX_DOUBLE
:
1466 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE
:
1471 /* Implementation of pure virtual hook recording::memento::replay_into
1472 for recording::memento_of_get_type. */
1475 recording::memento_of_get_type::replay_into (replayer
*r
)
1477 set_playback_obj (r
->get_type (m_kind
));
1480 /* The implementation of class gcc::jit::recording::memento_of_get_type. */
1482 /* Descriptive strings for each of enum gcc_jit_types. */
1484 static const char * const get_type_strings
[] = {
1485 "void", /* GCC_JIT_TYPE_VOID */
1486 "void *", /* GCC_JIT_TYPE_VOID_PTR */
1488 "bool", /* GCC_JIT_TYPE_BOOL */
1490 "char", /* GCC_JIT_TYPE_CHAR */
1491 "signed char", /* GCC_JIT_TYPE_SIGNED_CHAR */
1492 "unsigned char", /* GCC_JIT_TYPE_UNSIGNED_CHAR */
1494 "short", /* GCC_JIT_TYPE_SHORT */
1495 "unsigned short", /* GCC_JIT_TYPE_UNSIGNED_SHORT */
1497 "int", /* GCC_JIT_TYPE_INT */
1498 "unsigned int", /* GCC_JIT_TYPE_UNSIGNED_INT */
1500 "long", /* GCC_JIT_TYPE_LONG */
1501 "unsigned long", /* GCC_JIT_TYPE_UNSIGNED_LONG, */
1503 "long long", /* GCC_JIT_TYPE_LONG_LONG */
1504 "unsigned long long", /* GCC_JIT_TYPE_UNSIGNED_LONG_LONG */
1506 "float", /* GCC_JIT_TYPE_FLOAT */
1507 "double", /* GCC_JIT_TYPE_DOUBLE */
1508 "long double", /* GCC_JIT_TYPE_LONG_DOUBLE */
1510 "const char *", /* GCC_JIT_TYPE_CONST_CHAR_PTR */
1512 "size_t", /* GCC_JIT_TYPE_SIZE_T */
1514 "FILE *", /* GCC_JIT_TYPE_FILE_PTR */
1516 "complex float", /* GCC_JIT_TYPE_COMPLEX_FLOAT */
1517 "complex double", /* GCC_JIT_TYPE_COMPLEX_DOUBLE */
1518 "complex long double" /* GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE */
1522 /* Implementation of recording::memento::make_debug_string for
1523 results of get_type, using a simple table of type names. */
1526 recording::memento_of_get_type::make_debug_string ()
1528 return m_ctxt
->new_string (get_type_strings
[m_kind
]);
1531 /* The implementation of class gcc::jit::recording::memento_of_get_pointer. */
1533 /* Override of default implementation of
1534 recording::type::accepts_writes_from for get_pointer.
1536 Require a pointer type, and allowing writes to
1537 (const T *) from a (T*), but not the other way around. */
1540 recording::memento_of_get_pointer::accepts_writes_from (type
*rtype
)
1542 /* Must be a pointer type: */
1543 type
*rtype_points_to
= rtype
->is_pointer ();
1544 if (!rtype_points_to
)
1547 /* It's OK to assign to a (const T *) from a (T *). */
1548 return m_other_type
->unqualified ()
1549 ->accepts_writes_from (rtype_points_to
);
1552 /* Implementation of pure virtual hook recording::memento::replay_into
1553 for recording::memento_of_get_pointer. */
1556 recording::memento_of_get_pointer::replay_into (replayer
*)
1558 set_playback_obj (m_other_type
->playback_type ()->get_pointer ());
1561 /* Implementation of recording::memento::make_debug_string for
1562 results of get_pointer, adding " *" to the underlying type,
1563 with special-casing to handle function pointer types. */
1566 recording::memento_of_get_pointer::make_debug_string ()
1568 /* Special-case function pointer types, to put the "*" in parens between
1569 the return type and the params (for one level of dereferencing, at
1571 if (function_type
*fn_type
= m_other_type
->dyn_cast_function_type ())
1572 return fn_type
->make_debug_string_with_ptr ();
1574 return string::from_printf (m_ctxt
,
1575 "%s *", m_other_type
->get_debug_string ());
1578 /* The implementation of class gcc::jit::recording::memento_of_get_const. */
1580 /* Implementation of pure virtual hook recording::memento::replay_into
1581 for recording::memento_of_get_const. */
1584 recording::memento_of_get_const::replay_into (replayer
*)
1586 set_playback_obj (m_other_type
->playback_type ()->get_const ());
1589 /* Implementation of recording::memento::make_debug_string for
1590 results of get_const, prepending "const ". */
1593 recording::memento_of_get_const::make_debug_string ()
1595 return string::from_printf (m_ctxt
,
1596 "const %s", m_other_type
->get_debug_string ());
1599 /* The implementation of class gcc::jit::recording::memento_of_get_volatile. */
1601 /* Implementation of pure virtual hook recording::memento::replay_into
1602 for recording::memento_of_get_volatile. */
1605 recording::memento_of_get_volatile::replay_into (replayer
*)
1607 set_playback_obj (m_other_type
->playback_type ()->get_volatile ());
1610 /* Implementation of recording::memento::make_debug_string for
1611 results of get_volatile, prepending "volatile ". */
1614 recording::memento_of_get_volatile::make_debug_string ()
1616 return string::from_printf (m_ctxt
,
1617 "volatile %s", m_other_type
->get_debug_string ());
1620 /* The implementation of class gcc::jit::recording::array_type */
1622 /* Implementation of pure virtual hook recording::type::dereference for
1623 recording::array_type. */
1626 recording::array_type::dereference ()
1628 return m_element_type
;
1631 /* Implementation of pure virtual hook recording::memento::replay_into
1632 for recording::array_type. */
1635 recording::array_type::replay_into (replayer
*r
)
1637 set_playback_obj (r
->new_array_type (playback_location (r
, m_loc
),
1638 m_element_type
->playback_type (),
1642 /* Implementation of recording::memento::make_debug_string for
1643 results of new_array_type. */
1646 recording::array_type::make_debug_string ()
1648 return string::from_printf (m_ctxt
,
1650 m_element_type
->get_debug_string (),
1654 /* The implementation of class gcc::jit::recording::function_type */
1656 /* Constructor for gcc::jit::recording::function_type. */
1658 recording::function_type::function_type (context
*ctxt
,
1664 m_return_type (return_type
),
1666 m_is_variadic (is_variadic
)
1668 for (int i
= 0; i
< num_params
; i
++)
1669 m_param_types
.safe_push (param_types
[i
]);
1672 /* Implementation of pure virtual hook recording::type::dereference for
1673 recording::function_type. */
1676 recording::function_type::dereference ()
1681 /* Implementation of pure virtual hook recording::memento::replay_into
1682 for recording::function_type. */
1685 recording::function_type::replay_into (replayer
*r
)
1687 /* Convert m_param_types to a vec of playback type. */
1688 auto_vec
<playback::type
*> param_types
;
1690 recording::type
*type
;
1691 param_types
.create (m_param_types
.length ());
1692 FOR_EACH_VEC_ELT (m_param_types
, i
, type
)
1693 param_types
.safe_push (type
->playback_type ());
1695 set_playback_obj (r
->new_function_type (m_return_type
->playback_type (),
1700 /* Special-casing for make_debug_string for get_pointer results for
1701 handling (one level) of pointers to functions. */
1704 recording::function_type::make_debug_string_with_ptr ()
1706 return make_debug_string_with ("(*) ");
1709 /* Implementation of recording::memento::make_debug_string for
1710 results of new_function_type. */
1713 recording::function_type::make_debug_string ()
1715 return make_debug_string_with ("");
1718 /* Build a debug string representation of the form:
1720 RESULT_TYPE INSERT (PARAM_TYPES)
1722 for use when handling 0 and 1 level of indirection to this
1726 recording::function_type::make_debug_string_with (const char *insert
)
1728 /* First, build a buffer for the arguments. */
1729 /* Calculate length of said buffer. */
1730 size_t sz
= 1; /* nil terminator */
1731 for (unsigned i
= 0; i
< m_param_types
.length (); i
++)
1733 sz
+= strlen (m_param_types
[i
]->get_debug_string ());
1734 sz
+= 2; /* ", " separator */
1737 sz
+= 5; /* ", ..." separator and ellipsis */
1739 /* Now allocate and populate the buffer. */
1740 char *argbuf
= new char[sz
];
1743 for (unsigned i
= 0; i
< m_param_types
.length (); i
++)
1745 strcpy (argbuf
+ len
, m_param_types
[i
]->get_debug_string ());
1746 len
+= strlen (m_param_types
[i
]->get_debug_string ());
1747 if (i
+ 1 < m_param_types
.length ())
1749 strcpy (argbuf
+ len
, ", ");
1755 if (m_param_types
.length ())
1757 strcpy (argbuf
+ len
, ", ");
1760 strcpy (argbuf
+ len
, "...");
1765 /* ...and use it to get the string for the call as a whole. */
1766 string
*result
= string::from_printf (m_ctxt
,
1768 m_return_type
->get_debug_string (),
1777 /* The implementation of class gcc::jit::recording::field. */
1779 /* Implementation of pure virtual hook recording::memento::replay_into
1780 for recording::field. */
1783 recording::field::replay_into (replayer
*r
)
1785 set_playback_obj (r
->new_field (playback_location (r
, m_loc
),
1786 m_type
->playback_type (),
1787 playback_string (m_name
)));
1790 /* Override the default implementation of
1791 recording::memento::write_to_dump. Dump each field
1792 by dumping a line of the form:
1794 so that we can build up a struct/union field-byfield. */
1797 recording::field::write_to_dump (dump
&d
)
1799 d
.write (" %s %s;\n",
1800 m_type
->get_debug_string (),
1804 /* Implementation of recording::memento::make_debug_string for
1805 results of new_field. */
1808 recording::field::make_debug_string ()
1813 /* The implementation of class gcc::jit::recording::compound_type */
1815 /* The constructor for gcc::jit::recording::compound_type. */
1817 recording::compound_type::compound_type (context
*ctxt
,
1827 /* Set the fields of a compound type.
1829 Implements the post-error-checking part of
1830 gcc_jit_struct_set_fields, and is also used by
1831 gcc_jit_context_new_union_type. */
1834 recording::compound_type::set_fields (location
*loc
,
1836 field
**field_array
)
1839 gcc_assert (NULL
== m_fields
);
1841 m_fields
= new fields (this, num_fields
, field_array
);
1842 m_ctxt
->record (m_fields
);
1845 /* Implementation of pure virtual hook recording::type::dereference for
1846 recording::compound_type. */
1849 recording::compound_type::dereference ()
1851 return NULL
; /* not a pointer */
1854 /* The implementation of class gcc::jit::recording::struct_. */
1856 /* The constructor for gcc::jit::recording::struct_. */
1858 recording::struct_::struct_ (context
*ctxt
,
1861 : compound_type (ctxt
, loc
, name
)
1865 /* Implementation of pure virtual hook recording::memento::replay_into
1866 for recording::struct_. */
1869 recording::struct_::replay_into (replayer
*r
)
1872 r
->new_compound_type (playback_location (r
, get_loc ()),
1873 get_name ()->c_str (),
1874 true /* is_struct */));
1877 /* Implementation of recording::memento::make_debug_string for
1881 recording::struct_::make_debug_string ()
1883 return string::from_printf (m_ctxt
,
1884 "struct %s", get_name ()->c_str ());
1887 /* The implementation of class gcc::jit::recording::union_. */
1889 /* The constructor for gcc::jit::recording::union_. */
1891 recording::union_::union_ (context
*ctxt
,
1894 : compound_type (ctxt
, loc
, name
)
1898 /* Implementation of pure virtual hook recording::memento::replay_into
1899 for recording::union_. */
1902 recording::union_::replay_into (replayer
*r
)
1905 r
->new_compound_type (playback_location (r
, get_loc ()),
1906 get_name ()->c_str (),
1907 false /* is_struct */));
1910 /* Implementation of recording::memento::make_debug_string for
1914 recording::union_::make_debug_string ()
1916 return string::from_printf (m_ctxt
,
1917 "union %s", get_name ()->c_str ());
1920 /* The implementation of class gcc::jit::recording::fields. */
1922 /* The constructor for gcc::jit::recording::fields. */
1924 recording::fields::fields (compound_type
*struct_or_union
,
1927 : memento (struct_or_union
->m_ctxt
),
1928 m_struct_or_union (struct_or_union
),
1931 for (int i
= 0; i
< num_fields
; i
++)
1933 gcc_assert (fields
[i
]->get_container () == NULL
);
1934 fields
[i
]->set_container (m_struct_or_union
);
1935 m_fields
.safe_push (fields
[i
]);
1939 /* Implementation of pure virtual hook recording::memento::replay_into
1940 for recording::fields. */
1943 recording::fields::replay_into (replayer
*)
1945 auto_vec
<playback::field
*> playback_fields
;
1946 playback_fields
.create (m_fields
.length ());
1947 for (unsigned i
= 0; i
< m_fields
.length (); i
++)
1948 playback_fields
.safe_push (m_fields
[i
]->playback_field ());
1949 m_struct_or_union
->playback_compound_type ()->set_fields (&playback_fields
);
1952 /* Override the default implementation of
1953 recording::memento::write_to_dump by writing a union/struct
1954 declaration of this form:
1966 recording::fields::write_to_dump (dump
&d
)
1971 d
.write ("%s\n{\n", m_struct_or_union
->get_debug_string ());
1972 FOR_EACH_VEC_ELT (m_fields
, i
, f
)
1973 f
->write_to_dump (d
);
1977 /* Implementation of recording::memento::make_debug_string for
1981 recording::fields::make_debug_string ()
1983 return string::from_printf (m_ctxt
,
1987 /* The implementation of class gcc::jit::recording::rvalue. */
1989 /* Create a recording::access_field_rvalue instance and add it to
1990 the rvalue's context's list of mementos.
1992 Implements the post-error-checking part of
1993 gcc_jit_rvalue_access_field. */
1996 recording::rvalue::access_field (recording::location
*loc
,
1999 recording::rvalue
*result
=
2000 new access_field_rvalue (m_ctxt
, loc
, this, field
);
2001 m_ctxt
->record (result
);
2005 /* Create a recording::dereference_field_rvalue instance and add it to
2006 the rvalue's context's list of mementos.
2008 Implements the post-error-checking part of
2009 gcc_jit_rvalue_dereference_field. */
2012 recording::rvalue::dereference_field (recording::location
*loc
,
2015 recording::lvalue
*result
=
2016 new dereference_field_rvalue (m_ctxt
, loc
, this, field
);
2017 m_ctxt
->record (result
);
2021 /* Create a recording::dereference_rvalue instance and add it to the
2022 rvalue's context's list of mementos.
2024 Implements the post-error-checking part of
2025 gcc_jit_rvalue_dereference. */
2028 recording::rvalue::dereference (recording::location
*loc
)
2030 recording::lvalue
*result
=
2031 new dereference_rvalue (m_ctxt
, loc
, this);
2032 m_ctxt
->record (result
);
2036 /* The implementation of class gcc::jit::recording::lvalue. */
2038 /* Create a recording::new_access_field_of_lvalue instance and add it to
2039 the lvalue's context's list of mementos.
2041 Implements the post-error-checking part of
2042 gcc_jit_lvalue_access_field. */
2045 recording::lvalue::access_field (recording::location
*loc
,
2048 recording::lvalue
*result
=
2049 new access_field_of_lvalue (m_ctxt
, loc
, this, field
);
2050 m_ctxt
->record (result
);
2054 /* Create a recording::get_address_of_lvalue instance and add it to
2055 the lvalue's context's list of mementos.
2057 Implements the post-error-checking part of
2058 gcc_jit_lvalue_get_address. */
2061 recording::lvalue::get_address (recording::location
*loc
)
2063 recording::rvalue
*result
=
2064 new get_address_of_lvalue (m_ctxt
, loc
, this);
2065 m_ctxt
->record (result
);
2069 /* The implementation of class gcc::jit::recording::param. */
2071 /* Implementation of pure virtual hook recording::memento::replay_into
2072 for recording::param. */
2075 recording::param::replay_into (replayer
*r
)
2077 set_playback_obj (r
->new_param (playback_location (r
, m_loc
),
2078 m_type
->playback_type (),
2083 /* The implementation of class gcc::jit::recording::function. */
2085 /* gcc::jit::recording::function's constructor. */
2087 recording::function::function (context
*ctxt
,
2088 recording::location
*loc
,
2089 enum gcc_jit_function_kind kind
,
2091 recording::string
*name
,
2093 recording::param
**params
,
2095 enum built_in_function builtin_id
)
2099 m_return_type (return_type
),
2102 m_is_variadic (is_variadic
),
2103 m_builtin_id (builtin_id
),
2107 for (int i
= 0; i
< num_params
; i
++)
2108 m_params
.safe_push (params
[i
]);
2111 /* Implementation of pure virtual hook recording::memento::replay_into
2112 for recording::function. */
2115 recording::function::replay_into (replayer
*r
)
2117 /* Convert m_params to a vec of playback param. */
2118 auto_vec
<playback::param
*> params
;
2120 recording::param
*param
;
2121 params
.create (m_params
.length ());
2122 FOR_EACH_VEC_ELT (m_params
, i
, param
)
2123 params
.safe_push (param
->playback_param ());
2125 set_playback_obj (r
->new_function (playback_location (r
, m_loc
),
2127 m_return_type
->playback_type (),
2134 /* Create a recording::local instance and add it to
2135 the functions's context's list of mementos, and to the function's
2138 Implements the post-error-checking part of
2139 gcc_jit_function_new_local. */
2142 recording::function::new_local (recording::location
*loc
,
2146 local
*result
= new local (this, loc
, type
, new_string (name
));
2147 m_ctxt
->record (result
);
2148 m_locals
.safe_push (result
);
2152 /* Create a recording::block instance and add it to
2153 the functions's context's list of mementos, and to the function's
2156 Implements the post-error-checking part of
2157 gcc_jit_function_new_block. */
2160 recording::function::new_block (const char *name
)
2162 gcc_assert (m_kind
!= GCC_JIT_FUNCTION_IMPORTED
);
2164 recording::block
*result
=
2165 new recording::block (this, m_blocks
.length (), new_string (name
));
2166 m_ctxt
->record (result
);
2167 m_blocks
.safe_push (result
);
2171 /* Override the default implementation of
2172 recording::memento::write_to_dump by dumping a C-like
2173 representation of the function; either like a prototype
2174 for GCC_JIT_FUNCTION_IMPORTED, or like a full definition for
2175 all other kinds of function. */
2178 recording::function::write_to_dump (dump
&d
)
2182 default: gcc_unreachable ();
2183 case GCC_JIT_FUNCTION_EXPORTED
:
2184 case GCC_JIT_FUNCTION_IMPORTED
:
2185 d
.write ("extern ");
2187 case GCC_JIT_FUNCTION_INTERNAL
:
2188 d
.write ("static ");
2190 case GCC_JIT_FUNCTION_ALWAYS_INLINE
:
2191 d
.write ("static inline ");
2194 d
.write ("%s\n", m_return_type
->get_debug_string ());
2196 if (d
.update_locations ())
2197 m_loc
= d
.make_location ();
2199 d
.write ("%s (", get_debug_string ());
2202 recording::param
*param
;
2203 FOR_EACH_VEC_ELT (m_params
, i
, param
)
2208 param
->get_type ()->get_debug_string (),
2209 param
->get_debug_string ());
2212 if (m_kind
== GCC_JIT_FUNCTION_IMPORTED
)
2214 d
.write ("; /* (imported) */\n\n");
2224 FOR_EACH_VEC_ELT (m_locals
, i
, var
)
2225 var
->write_to_dump (d
);
2226 if (m_locals
.length ())
2229 /* Write each block: */
2230 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
2234 b
->write_to_dump (d
);
2241 /* Pre-compilation validation of a function, for those things we can't
2242 check until the context is (supposedly) fully-populated. */
2245 recording::function::validate ()
2247 /* Complain about empty functions with non-void return type. */
2248 if (m_kind
!= GCC_JIT_FUNCTION_IMPORTED
2249 && m_return_type
!= m_ctxt
->get_type (GCC_JIT_TYPE_VOID
))
2250 if (0 == m_blocks
.length ())
2251 m_ctxt
->add_error (m_loc
,
2252 "function %s returns non-void (type: %s)"
2253 " but has no blocks",
2254 get_debug_string (),
2255 m_return_type
->get_debug_string ());
2257 /* Check that all blocks are terminated. */
2258 int num_invalid_blocks
= 0;
2263 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
2264 if (!b
->validate ())
2265 num_invalid_blocks
++;
2268 /* Check that all blocks are reachable. */
2269 if (m_blocks
.length () > 0 && 0 == num_invalid_blocks
)
2271 /* Iteratively walk the graph of blocks, marking their "m_is_reachable"
2272 flag, starting at the initial block. */
2273 auto_vec
<block
*> worklist (m_blocks
.length ());
2274 worklist
.safe_push (m_blocks
[0]);
2275 while (worklist
.length () > 0)
2277 block
*b
= worklist
.pop ();
2278 b
->m_is_reachable
= true;
2280 /* Add successor blocks that aren't yet marked to the worklist. */
2281 /* We checked that each block has a terminating statement above . */
2282 block
*next1
, *next2
;
2283 int n
= b
->get_successor_blocks (&next1
, &next2
);
2289 if (!next2
->m_is_reachable
)
2290 worklist
.safe_push (next2
);
2293 if (!next1
->m_is_reachable
)
2294 worklist
.safe_push (next1
);
2301 /* Now complain about any blocks that haven't been marked. */
2305 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
2306 if (!b
->m_is_reachable
)
2307 m_ctxt
->add_error (b
->get_loc (),
2308 "unreachable block: %s",
2309 b
->get_debug_string ());
2314 /* Implements the post-error-checking part of
2315 gcc_jit_function_dump_to_dot. */
2318 recording::function::dump_to_dot (const char *path
)
2320 FILE *fp
= fopen (path
, "w");
2324 pretty_printer the_pp
;
2325 the_pp
.buffer
->stream
= fp
;
2327 pretty_printer
*pp
= &the_pp
;
2330 "digraph %s {\n", get_debug_string ());
2336 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
2337 b
->dump_to_dot (pp
);
2344 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
2345 b
->dump_edges_to_dot (pp
);
2348 pp_printf (pp
, "}\n");
2353 /* Implementation of recording::memento::make_debug_string for
2357 recording::function::make_debug_string ()
2362 /* The implementation of class gcc::jit::recording::block. */
2364 /* Create a recording::eval instance and add it to
2365 the block's context's list of mementos, and to the block's
2368 Implements the post-error-checking part of
2369 gcc_jit_block_add_eval. */
2372 recording::block::add_eval (recording::location
*loc
,
2373 recording::rvalue
*rvalue
)
2375 statement
*result
= new eval (this, loc
, rvalue
);
2376 m_ctxt
->record (result
);
2377 m_statements
.safe_push (result
);
2380 /* Create a recording::assignment instance and add it to
2381 the block's context's list of mementos, and to the block's
2384 Implements the post-error-checking part of
2385 gcc_jit_block_add_assignment. */
2388 recording::block::add_assignment (recording::location
*loc
,
2389 recording::lvalue
*lvalue
,
2390 recording::rvalue
*rvalue
)
2392 statement
*result
= new assignment (this, loc
, lvalue
, rvalue
);
2393 m_ctxt
->record (result
);
2394 m_statements
.safe_push (result
);
2397 /* Create a recording::assignment_op instance and add it to
2398 the block's context's list of mementos, and to the block's
2401 Implements the post-error-checking part of
2402 gcc_jit_block_add_assignment_op. */
2405 recording::block::add_assignment_op (recording::location
*loc
,
2406 recording::lvalue
*lvalue
,
2407 enum gcc_jit_binary_op op
,
2408 recording::rvalue
*rvalue
)
2410 statement
*result
= new assignment_op (this, loc
, lvalue
, op
, rvalue
);
2411 m_ctxt
->record (result
);
2412 m_statements
.safe_push (result
);
2415 /* Create a recording::comment instance and add it to
2416 the block's context's list of mementos, and to the block's
2419 Implements the post-error-checking part of
2420 gcc_jit_block_add_comment. */
2423 recording::block::add_comment (recording::location
*loc
,
2426 statement
*result
= new comment (this, loc
, new_string (text
));
2427 m_ctxt
->record (result
);
2428 m_statements
.safe_push (result
);
2431 /* Create a recording::end_with_conditional instance and add it to
2432 the block's context's list of mementos, and to the block's
2435 Implements the post-error-checking part of
2436 gcc_jit_block_end_with_conditional. */
2439 recording::block::end_with_conditional (recording::location
*loc
,
2440 recording::rvalue
*boolval
,
2441 recording::block
*on_true
,
2442 recording::block
*on_false
)
2444 statement
*result
= new conditional (this, loc
, boolval
, on_true
, on_false
);
2445 m_ctxt
->record (result
);
2446 m_statements
.safe_push (result
);
2447 m_has_been_terminated
= true;
2450 /* Create a recording::end_with_jump instance and add it to
2451 the block's context's list of mementos, and to the block's
2454 Implements the post-error-checking part of
2455 gcc_jit_block_end_with_jump. */
2458 recording::block::end_with_jump (recording::location
*loc
,
2459 recording::block
*target
)
2461 statement
*result
= new jump (this, loc
, target
);
2462 m_ctxt
->record (result
);
2463 m_statements
.safe_push (result
);
2464 m_has_been_terminated
= true;
2467 /* Create a recording::end_with_return instance and add it to
2468 the block's context's list of mementos, and to the block's
2471 Implements the post-error-checking parts of
2472 gcc_jit_block_end_with_return and
2473 gcc_jit_block_end_with_void_return. */
2476 recording::block::end_with_return (recording::location
*loc
,
2477 recording::rvalue
*rvalue
)
2479 /* This is used by both gcc_jit_function_add_return and
2480 gcc_jit_function_add_void_return; rvalue will be non-NULL for
2481 the former and NULL for the latter. */
2482 statement
*result
= new return_ (this, loc
, rvalue
);
2483 m_ctxt
->record (result
);
2484 m_statements
.safe_push (result
);
2485 m_has_been_terminated
= true;
2488 /* Override the default implementation of
2489 recording::memento::write_to_dump for blocks by writing
2490 an unindented block name as a label, followed by the indented
2500 recording::block::write_to_dump (dump
&d
)
2502 d
.write ("%s:\n", get_debug_string ());
2506 FOR_EACH_VEC_ELT (m_statements
, i
, s
)
2507 s
->write_to_dump (d
);
2510 /* Validate a block by ensuring that it has been terminated. */
2513 recording::block::validate ()
2515 if (!has_been_terminated ())
2517 statement
*stmt
= get_last_statement ();
2518 location
*loc
= stmt
? stmt
->get_loc () : NULL
;
2519 m_func
->get_context ()->add_error (loc
,
2520 "unterminated block in %s: %s",
2521 m_func
->get_debug_string (),
2522 get_debug_string ());
2529 /* Get the source-location of a block by using that of the first
2530 statement within it, if any. */
2532 recording::location
*
2533 recording::block::get_loc () const
2535 recording::statement
*stmt
= get_first_statement ();
2537 return stmt
->get_loc ();
2542 /* Get the first statement within a block, if any. */
2544 recording::statement
*
2545 recording::block::get_first_statement () const
2547 if (m_statements
.length ())
2548 return m_statements
[0];
2553 /* Get the last statement within a block, if any. */
2555 recording::statement
*
2556 recording::block::get_last_statement () const
2558 if (m_statements
.length ())
2559 return m_statements
[m_statements
.length () - 1];
2564 /* Assuming that this block has been terminated, get the number of
2565 successor blocks, which will be 0, 1 or 2, for return, unconditional
2566 jump, and conditional jump respectively.
2567 NEXT1 and NEXT2 must be non-NULL. The first successor block (if any)
2568 is written to NEXT1, and the second (if any) to NEXT2.
2570 Used when validating functions, and when dumping dot representations
2574 recording::block::get_successor_blocks (block
**next1
, block
**next2
) const
2576 gcc_assert (m_has_been_terminated
);
2579 statement
*last_statement
= get_last_statement ();
2580 gcc_assert (last_statement
);
2581 return last_statement
->get_successor_blocks (next1
, next2
);
2584 /* Implementation of pure virtual hook recording::memento::replay_into
2585 for recording::block. */
2588 recording::block::replay_into (replayer
*)
2590 set_playback_obj (m_func
->playback_function ()
2591 ->new_block (playback_string (m_name
)));
2594 /* Implementation of recording::memento::make_debug_string for
2598 recording::block::make_debug_string ()
2603 return string::from_printf (m_ctxt
,
2604 "<UNNAMED BLOCK %p>",
2608 /* Dump a block in graphviz form into PP, capturing the block name (if
2609 any) and the statements. */
2612 recording::block::dump_to_dot (pretty_printer
*pp
)
2616 "[shape=record,style=filled,fillcolor=white,label=\"{"),
2618 pp_write_text_to_stream (pp
);
2621 pp_string (pp
, m_name
->c_str ());
2622 pp_string (pp
, ":");
2624 pp_write_text_as_dot_label_to_stream (pp
, true /*for_record*/);
2629 FOR_EACH_VEC_ELT (m_statements
, i
, s
)
2631 pp_string (pp
, s
->get_debug_string ());
2633 pp_write_text_as_dot_label_to_stream (pp
, true /*for_record*/);
2641 /* Dump the out-edges of the block in graphviz form into PP. */
2644 recording::block::dump_edges_to_dot (pretty_printer
*pp
)
2647 int num_succs
= get_successor_blocks (&next
[0], &next
[1]);
2648 for (int i
= 0; i
< num_succs
; i
++)
2650 "\tblock_%d:s -> block_%d:n;\n",
2651 m_index
, next
[i
]->m_index
);
2654 /* The implementation of class gcc::jit::recording::global. */
2656 /* Implementation of pure virtual hook recording::memento::replay_into
2657 for recording::global. */
2660 recording::global::replay_into (replayer
*r
)
2662 set_playback_obj (r
->new_global (playback_location (r
, m_loc
),
2663 m_type
->playback_type (),
2664 playback_string (m_name
)));
2667 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_int. */
2669 /* Implementation of pure virtual hook recording::memento::replay_into
2670 for recording::memento_of_new_rvalue_from_int. */
2673 recording::memento_of_new_rvalue_from_int::replay_into (replayer
*r
)
2675 set_playback_obj (r
->new_rvalue_from_int (m_type
->playback_type (),
2679 /* Implementation of recording::memento::make_debug_string for
2680 rvalue_from_int, rendering it as
2686 recording::memento_of_new_rvalue_from_int::make_debug_string ()
2688 return string::from_printf (m_ctxt
,
2690 m_type
->get_debug_string (),
2694 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_double. */
2696 /* Implementation of pure virtual hook recording::memento::replay_into
2697 for recording::memento_of_new_rvalue_from_double. */
2700 recording::memento_of_new_rvalue_from_double::replay_into (replayer
*r
)
2702 set_playback_obj (r
->new_rvalue_from_double (m_type
->playback_type (),
2706 /* Implementation of recording::memento::make_debug_string for
2707 rvalue_from_double, rendering it as
2713 recording::memento_of_new_rvalue_from_double::make_debug_string ()
2715 return string::from_printf (m_ctxt
,
2717 m_type
->get_debug_string (),
2721 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_ptr. */
2723 /* Implementation of pure virtual hook recording::memento::replay_into
2724 for recording::memento_of_new_rvalue_from_ptr. */
2727 recording::memento_of_new_rvalue_from_ptr::replay_into (replayer
*r
)
2729 set_playback_obj (r
->new_rvalue_from_ptr (m_type
->playback_type (),
2733 /* Implementation of recording::memento::make_debug_string for
2734 rvalue_from_ptr, rendering it as
2739 Zero is rendered as NULL e.g.
2743 recording::memento_of_new_rvalue_from_ptr::make_debug_string ()
2745 if (m_value
!= NULL
)
2746 return string::from_printf (m_ctxt
,
2748 m_type
->get_debug_string (), m_value
);
2750 return string::from_printf (m_ctxt
,
2752 m_type
->get_debug_string ());
2755 /* The implementation of class gcc::jit::recording::memento_of_new_string_literal. */
2757 /* Implementation of pure virtual hook recording::memento::replay_into
2758 for recording::memento_of_new_string_literal. */
2761 recording::memento_of_new_string_literal::replay_into (replayer
*r
)
2763 set_playback_obj (r
->new_string_literal (m_value
->c_str ()));
2766 /* Implementation of recording::memento::make_debug_string for
2770 recording::memento_of_new_string_literal::make_debug_string ()
2772 return string::from_printf (m_ctxt
,
2773 m_value
->get_debug_string ());
2776 /* The implementation of class gcc::jit::recording::unary_op. */
2778 /* Implementation of pure virtual hook recording::memento::replay_into
2779 for recording::unary_op. */
2782 recording::unary_op::replay_into (replayer
*r
)
2784 set_playback_obj (r
->new_unary_op (playback_location (r
, m_loc
),
2786 get_type ()->playback_type (),
2787 m_a
->playback_rvalue ()));
2790 /* Implementation of recording::memento::make_debug_string for
2793 static const char * const unary_op_strings
[] = {
2794 "-", /* GCC_JIT_UNARY_OP_MINUS */
2795 "~", /* GCC_JIT_UNARY_OP_BITWISE_NEGATE */
2796 "!", /* GCC_JIT_UNARY_OP_LOGICAL_NEGATE */
2800 recording::unary_op::make_debug_string ()
2802 return string::from_printf (m_ctxt
,
2804 unary_op_strings
[m_op
],
2805 m_a
->get_debug_string ());
2808 /* The implementation of class gcc::jit::recording::binary_op. */
2810 /* Implementation of pure virtual hook recording::memento::replay_into
2811 for recording::binary_op. */
2814 recording::binary_op::replay_into (replayer
*r
)
2816 set_playback_obj (r
->new_binary_op (playback_location (r
, m_loc
),
2818 get_type ()->playback_type (),
2819 m_a
->playback_rvalue (),
2820 m_b
->playback_rvalue ()));
2823 /* Implementation of recording::memento::make_debug_string for
2826 static const char * const binary_op_strings
[] = {
2827 "+", /* GCC_JIT_BINARY_OP_PLUS */
2828 "-", /* GCC_JIT_BINARY_OP_MINUS */
2829 "*", /* GCC_JIT_BINARY_OP_MULT */
2830 "/", /* GCC_JIT_BINARY_OP_DIVIDE */
2831 "%", /* GCC_JIT_BINARY_OP_MODULO */
2832 "&", /* GCC_JIT_BINARY_OP_BITWISE_AND */
2833 "^", /* GCC_JIT_BINARY_OP_BITWISE_XOR */
2834 "|", /* GCC_JIT_BINARY_OP_BITWISE_OR */
2835 "&&", /* GCC_JIT_BINARY_OP_LOGICAL_AND */
2836 "||", /* GCC_JIT_BINARY_OP_LOGICAL_OR */
2837 "<<", /* GCC_JIT_BINARY_OP_LSHIFT */
2838 ">>", /* GCC_JIT_BINARY_OP_RSHIFT */
2842 recording::binary_op::make_debug_string ()
2844 return string::from_printf (m_ctxt
,
2846 m_a
->get_debug_string (),
2847 binary_op_strings
[m_op
],
2848 m_b
->get_debug_string ());
2851 /* The implementation of class gcc::jit::recording::comparison. */
2853 /* Implementation of recording::memento::make_debug_string for
2856 static const char * const comparison_strings
[] =
2858 "==", /* GCC_JIT_COMPARISON_EQ */
2859 "!=", /* GCC_JIT_COMPARISON_NE */
2860 "<", /* GCC_JIT_COMPARISON_LT */
2861 "<=", /* GCC_JIT_COMPARISON_LE */
2862 ">", /* GCC_JIT_COMPARISON_GT */
2863 ">=", /* GCC_JIT_COMPARISON_GE */
2867 recording::comparison::make_debug_string ()
2869 return string::from_printf (m_ctxt
,
2871 m_a
->get_debug_string (),
2872 comparison_strings
[m_op
],
2873 m_b
->get_debug_string ());
2876 /* Implementation of pure virtual hook recording::memento::replay_into
2877 for recording::comparison. */
2880 recording::comparison::replay_into (replayer
*r
)
2882 set_playback_obj (r
->new_comparison (playback_location (r
, m_loc
),
2884 m_a
->playback_rvalue (),
2885 m_b
->playback_rvalue ()));
2888 /* Implementation of pure virtual hook recording::memento::replay_into
2889 for recording::cast. */
2892 recording::cast::replay_into (replayer
*r
)
2894 set_playback_obj (r
->new_cast (playback_location (r
, m_loc
),
2895 m_rvalue
->playback_rvalue (),
2896 get_type ()->playback_type ()));
2899 /* Implementation of recording::memento::make_debug_string for
2903 recording::cast::make_debug_string ()
2905 return string::from_printf (m_ctxt
,
2907 get_type ()->get_debug_string (),
2908 m_rvalue
->get_debug_string ());
2911 /* The implementation of class gcc::jit::recording::call. */
2913 /* The constructor for gcc::jit::recording::call. */
2915 recording::call::call (recording::context
*ctxt
,
2916 recording::location
*loc
,
2917 recording::function
*func
,
2920 : rvalue (ctxt
, loc
, func
->get_return_type ()),
2924 for (int i
= 0; i
< numargs
; i
++)
2925 m_args
.safe_push (args
[i
]);
2928 /* Implementation of pure virtual hook recording::memento::replay_into
2929 for recording::call. */
2932 recording::call::replay_into (replayer
*r
)
2934 auto_vec
<playback::rvalue
*> playback_args
;
2935 playback_args
.create (m_args
.length ());
2936 for (unsigned i
= 0; i
< m_args
.length (); i
++)
2937 playback_args
.safe_push (m_args
[i
]->playback_rvalue ());
2939 set_playback_obj (r
->new_call (playback_location (r
, m_loc
),
2940 m_func
->playback_function (),
2944 /* Implementation of recording::memento::make_debug_string for
2948 recording::call::make_debug_string ()
2950 /* First, build a buffer for the arguments. */
2951 /* Calculate length of said buffer. */
2952 size_t sz
= 1; /* nil terminator */
2953 for (unsigned i
= 0; i
< m_args
.length (); i
++)
2955 sz
+= strlen (m_args
[i
]->get_debug_string ());
2956 sz
+= 2; /* ", " separator */
2959 /* Now allocate and populate the buffer. */
2960 char *argbuf
= new char[sz
];
2963 for (unsigned i
= 0; i
< m_args
.length (); i
++)
2965 strcpy (argbuf
+ len
, m_args
[i
]->get_debug_string ());
2966 len
+= strlen (m_args
[i
]->get_debug_string ());
2967 if (i
+ 1 < m_args
.length ())
2969 strcpy (argbuf
+ len
, ", ");
2975 /* ...and use it to get the string for the call as a whole. */
2976 string
*result
= string::from_printf (m_ctxt
,
2978 m_func
->get_debug_string (),
2986 /* The implementation of class gcc::jit::recording::call_through_ptr. */
2988 /* The constructor for recording::call_through_ptr. */
2990 recording::call_through_ptr::call_through_ptr (recording::context
*ctxt
,
2991 recording::location
*loc
,
2992 recording::rvalue
*fn_ptr
,
2995 : rvalue (ctxt
, loc
,
2996 fn_ptr
->get_type ()->dereference ()
2997 ->as_a_function_type ()->get_return_type ()),
3001 for (int i
= 0; i
< numargs
; i
++)
3002 m_args
.safe_push (args
[i
]);
3005 /* Implementation of pure virtual hook recording::memento::replay_into
3006 for recording::call_through_ptr. */
3009 recording::call_through_ptr::replay_into (replayer
*r
)
3011 auto_vec
<playback::rvalue
*> playback_args
;
3012 playback_args
.create (m_args
.length ());
3013 for (unsigned i
= 0; i
< m_args
.length (); i
++)
3014 playback_args
.safe_push (m_args
[i
]->playback_rvalue ());
3016 set_playback_obj (r
->new_call_through_ptr (playback_location (r
, m_loc
),
3017 m_fn_ptr
->playback_rvalue (),
3021 /* Implementation of recording::memento::make_debug_string for
3022 calls through function ptrs. */
3025 recording::call_through_ptr::make_debug_string ()
3027 /* First, build a buffer for the arguments. */
3028 /* Calculate length of said buffer. */
3029 size_t sz
= 1; /* nil terminator */
3030 for (unsigned i
= 0; i
< m_args
.length (); i
++)
3032 sz
+= strlen (m_args
[i
]->get_debug_string ());
3033 sz
+= 2; /* ", " separator */
3036 /* Now allocate and populate the buffer. */
3037 char *argbuf
= new char[sz
];
3040 for (unsigned i
= 0; i
< m_args
.length (); i
++)
3042 strcpy (argbuf
+ len
, m_args
[i
]->get_debug_string ());
3043 len
+= strlen (m_args
[i
]->get_debug_string ());
3044 if (i
+ 1 < m_args
.length ())
3046 strcpy (argbuf
+ len
, ", ");
3052 /* ...and use it to get the string for the call as a whole. */
3053 string
*result
= string::from_printf (m_ctxt
,
3055 m_fn_ptr
->get_debug_string (),
3063 /* The implementation of class gcc::jit::recording::array_access. */
3065 /* Implementation of pure virtual hook recording::memento::replay_into
3066 for recording::array_access. */
3069 recording::array_access::replay_into (replayer
*r
)
3072 r
->new_array_access (playback_location (r
, m_loc
),
3073 m_ptr
->playback_rvalue (),
3074 m_index
->playback_rvalue ()));
3077 /* Implementation of recording::memento::make_debug_string for
3081 recording::array_access::make_debug_string ()
3083 return string::from_printf (m_ctxt
,
3085 m_ptr
->get_debug_string (),
3086 m_index
->get_debug_string ());
3089 /* The implementation of class gcc::jit::recording::access_field_of_lvalue. */
3091 /* Implementation of pure virtual hook recording::memento::replay_into
3092 for recording::access_field_of_lvalue. */
3095 recording::access_field_of_lvalue::replay_into (replayer
*r
)
3098 m_lvalue
->playback_lvalue ()
3099 ->access_field (playback_location (r
, m_loc
),
3100 m_field
->playback_field ()));
3104 /* Implementation of recording::memento::make_debug_string for
3105 accessing a field of an lvalue. */
3108 recording::access_field_of_lvalue::make_debug_string ()
3110 return string::from_printf (m_ctxt
,
3112 m_lvalue
->get_debug_string (),
3113 m_field
->get_debug_string ());
3116 /* The implementation of class gcc::jit::recording::access_field_rvalue. */
3118 /* Implementation of pure virtual hook recording::memento::replay_into
3119 for recording::access_field_rvalue. */
3122 recording::access_field_rvalue::replay_into (replayer
*r
)
3125 m_rvalue
->playback_rvalue ()
3126 ->access_field (playback_location (r
, m_loc
),
3127 m_field
->playback_field ()));
3130 /* Implementation of recording::memento::make_debug_string for
3131 accessing a field of an rvalue. */
3134 recording::access_field_rvalue::make_debug_string ()
3136 return string::from_printf (m_ctxt
,
3138 m_rvalue
->get_debug_string (),
3139 m_field
->get_debug_string ());
3142 /* The implementation of class
3143 gcc::jit::recording::dereference_field_rvalue. */
3145 /* Implementation of pure virtual hook recording::memento::replay_into
3146 for recording::dereference_field_rvalue. */
3149 recording::dereference_field_rvalue::replay_into (replayer
*r
)
3152 m_rvalue
->playback_rvalue ()->
3153 dereference_field (playback_location (r
, m_loc
),
3154 m_field
->playback_field ()));
3157 /* Implementation of recording::memento::make_debug_string for
3158 dereferencing a field of an rvalue. */
3161 recording::dereference_field_rvalue::make_debug_string ()
3163 return string::from_printf (m_ctxt
,
3165 m_rvalue
->get_debug_string (),
3166 m_field
->get_debug_string ());
3169 /* The implementation of class gcc::jit::recording::dereference_rvalue. */
3171 /* Implementation of pure virtual hook recording::memento::replay_into
3172 for recording::dereference_rvalue. */
3175 recording::dereference_rvalue::replay_into (replayer
*r
)
3178 m_rvalue
->playback_rvalue ()->
3179 dereference (playback_location (r
, m_loc
)));
3182 /* Implementation of recording::memento::make_debug_string for
3183 dereferencing an rvalue. */
3186 recording::dereference_rvalue::make_debug_string ()
3188 return string::from_printf (m_ctxt
,
3190 m_rvalue
->get_debug_string ());
3193 /* The implementation of class gcc::jit::recording::get_address_of_lvalue. */
3195 /* Implementation of pure virtual hook recording::memento::replay_into
3196 for recording::get_address_of_lvalue. */
3199 recording::get_address_of_lvalue::replay_into (replayer
*r
)
3202 m_lvalue
->playback_lvalue ()->
3203 get_address (playback_location (r
, m_loc
)));
3206 /* Implementation of recording::memento::make_debug_string for
3207 getting the address of an lvalue. */
3210 recording::get_address_of_lvalue::make_debug_string ()
3212 return string::from_printf (m_ctxt
,
3214 m_lvalue
->get_debug_string ());
3217 /* The implementation of class gcc::jit::recording::local. */
3219 /* Implementation of pure virtual hook recording::memento::replay_into
3220 for recording::local. */
3223 recording::local::replay_into (replayer
*r
)
3226 m_func
->playback_function ()
3227 ->new_local (playback_location (r
, m_loc
),
3228 m_type
->playback_type (),
3229 playback_string (m_name
)));
3232 /* Override the default implementation of
3233 recording::memento::write_to_dump for locals by writing
3235 for use at the top of the function body as if it were a
3239 recording::local::write_to_dump (dump
&d
)
3241 if (d
.update_locations ())
3242 m_loc
= d
.make_location ();
3243 d
.write(" %s %s;\n",
3244 m_type
->get_debug_string (),
3245 get_debug_string ());
3248 /* The implementation of class gcc::jit::recording::statement. */
3250 /* We poison the default implementation of
3251 gcc::jit::recording::statement::get_successor_blocks
3252 since this vfunc must only ever be called on terminator
3256 recording::statement::get_successor_blocks (block
**/
*out_next1*/
,
3257 block
**/
*out_next2*/
) const
3259 /* The base class implementation is for non-terminating statements,
3260 and thus should never be called. */
3265 /* Extend the default implementation of
3266 recording::memento::write_to_dump for statements by (if requested)
3267 updating the location of the statement to the current location in
3271 recording::statement::write_to_dump (dump
&d
)
3273 memento::write_to_dump (d
);
3274 if (d
.update_locations ())
3275 m_loc
= d
.make_location ();
3278 /* The implementation of class gcc::jit::recording::eval. */
3280 /* Implementation of pure virtual hook recording::memento::replay_into
3281 for recording::eval. */
3284 recording::eval::replay_into (replayer
*r
)
3286 playback_block (get_block ())
3287 ->add_eval (playback_location (r
),
3288 m_rvalue
->playback_rvalue ());
3291 /* Implementation of recording::memento::make_debug_string for
3292 an eval statement. */
3295 recording::eval::make_debug_string ()
3297 return string::from_printf (m_ctxt
,
3299 m_rvalue
->get_debug_string ());
3302 /* The implementation of class gcc::jit::recording::assignment. */
3304 /* Implementation of pure virtual hook recording::memento::replay_into
3305 for recording::assignment. */
3308 recording::assignment::replay_into (replayer
*r
)
3310 playback_block (get_block ())
3311 ->add_assignment (playback_location (r
),
3312 m_lvalue
->playback_lvalue (),
3313 m_rvalue
->playback_rvalue ());
3316 /* Implementation of recording::memento::make_debug_string for
3317 an assignment statement. */
3320 recording::assignment::make_debug_string ()
3322 return string::from_printf (m_ctxt
,
3324 m_lvalue
->get_debug_string (),
3325 m_rvalue
->get_debug_string ());
3328 /* The implementation of class gcc::jit::recording::assignment_op. */
3330 /* Implementation of pure virtual hook recording::memento::replay_into
3331 for recording::assignment_op. */
3334 recording::assignment_op::replay_into (replayer
*r
)
3336 playback::type
*result_type
=
3337 m_lvalue
->playback_lvalue ()->get_type ();
3339 playback::rvalue
*binary_op
=
3340 r
->new_binary_op (playback_location (r
),
3343 m_lvalue
->playback_rvalue (),
3344 m_rvalue
->playback_rvalue ());
3346 playback_block (get_block ())
3347 ->add_assignment (playback_location (r
),
3348 m_lvalue
->playback_lvalue (),
3352 /* Implementation of recording::memento::make_debug_string for
3353 an assignment_op statement. */
3356 recording::assignment_op::make_debug_string ()
3358 return string::from_printf (m_ctxt
,
3360 m_lvalue
->get_debug_string (),
3361 binary_op_strings
[m_op
],
3362 m_rvalue
->get_debug_string ());
3365 /* The implementation of class gcc::jit::recording::comment. */
3367 /* Implementation of pure virtual hook recording::memento::replay_into
3368 for recording::comment. */
3371 recording::comment::replay_into (replayer
*r
)
3373 playback_block (get_block ())
3374 ->add_comment (playback_location (r
),
3378 /* Implementation of recording::memento::make_debug_string for
3379 a comment "statement". */
3382 recording::comment::make_debug_string ()
3384 return string::from_printf (m_ctxt
,
3389 /* The implementation of class gcc::jit::recording::conditional. */
3391 /* Implementation of pure virtual hook recording::memento::replay_into
3392 for recording::conditional. */
3395 recording::conditional::replay_into (replayer
*r
)
3397 playback_block (get_block ())
3398 ->add_conditional (playback_location (r
),
3399 m_boolval
->playback_rvalue (),
3400 playback_block (m_on_true
),
3401 playback_block (m_on_false
));
3404 /* Override the poisoned default implementation of
3405 gcc::jit::recording::statement::get_successor_blocks
3407 A conditional jump has 2 successor blocks. */
3410 recording::conditional::get_successor_blocks (block
**out_next1
,
3411 block
**out_next2
) const
3413 *out_next1
= m_on_true
;
3414 *out_next2
= m_on_false
;
3418 /* Implementation of recording::memento::make_debug_string for
3419 a conditional jump statement. */
3422 recording::conditional::make_debug_string ()
3425 return string::from_printf (m_ctxt
,
3426 "if (%s) goto %s; else goto %s;",
3427 m_boolval
->get_debug_string (),
3428 m_on_true
->get_debug_string (),
3429 m_on_false
->get_debug_string ());
3431 return string::from_printf (m_ctxt
,
3433 m_boolval
->get_debug_string (),
3434 m_on_true
->get_debug_string ());
3437 /* The implementation of class gcc::jit::recording::jump. */
3439 /* Implementation of pure virtual hook recording::memento::replay_into
3440 for recording::jump. */
3443 recording::jump::replay_into (replayer
*r
)
3445 playback_block (get_block ())
3446 ->add_jump (playback_location (r
),
3447 m_target
->playback_block ());
3450 /* Override the poisoned default implementation of
3451 gcc::jit::recording::statement::get_successor_blocks
3453 An unconditional jump has 1 successor block. */
3456 recording::jump::get_successor_blocks (block
**out_next1
,
3457 block
**/
*out_next2*/
) const
3459 *out_next1
= m_target
;
3463 /* Implementation of recording::memento::make_debug_string for
3464 a unconditional jump statement. */
3467 recording::jump::make_debug_string ()
3469 return string::from_printf (m_ctxt
,
3471 m_target
->get_debug_string ());
3474 /* The implementation of class gcc::jit::recording::return_. */
3476 /* Implementation of pure virtual hook recording::memento::replay_into
3477 for recording::return_. */
3480 recording::return_::replay_into (replayer
*r
)
3482 playback_block (get_block ())
3483 ->add_return (playback_location (r
),
3484 m_rvalue
? m_rvalue
->playback_rvalue () : NULL
);
3487 /* Override the poisoned default implementation of
3488 gcc::jit::recording::statement::get_successor_blocks
3490 A return statement has no successor block. */
3493 recording::return_::get_successor_blocks (block
**/
*out_next1*/
,
3494 block
**/
*out_next2*/
) const
3499 /* Implementation of recording::memento::make_debug_string for
3500 a return statement (covers both those with and without rvalues). */
3503 recording::return_::make_debug_string ()
3506 return string::from_printf (m_ctxt
,
3508 m_rvalue
->get_debug_string ());
3510 return string::from_printf (m_ctxt
,
3514 } // namespace gcc::jit