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 if (m_builtins_manager
)
219 delete m_builtins_manager
;
221 if (m_owns_first_error_str
)
222 free (m_first_error_str
);
225 /* Add the given mememto to the list of those tracked by this
226 gcc::jit::recording::context, so that e.g. it can be deleted
227 when this context is released. */
230 recording::context::record (memento
*m
)
234 m_mementos
.safe_push (m
);
237 /* Replay this context (and any parents) into the given replayer. */
240 recording::context::replay_into (replayer
*r
)
245 /* If we have a parent context, we must replay it. This will
246 recursively walk backwards up the historical tree, then replay things
247 forwards "in historical order", starting with the ultimate parent
248 context, until we reach the "this" context.
250 Note that we fully replay the parent, then fully replay the child,
251 which means that inter-context references can only exist from child
252 to parent, not the other way around.
254 All of this replaying is suboptimal - it would be better to do the
255 work for the parent context *once*, rather than replaying the parent
256 every time we replay each child. However, fixing this requires deep
257 surgery to lifetime-management: we'd need every context family tree
258 to have its own GC heap, and to initialize the GCC code to use that
259 heap (with a mutex on such a heap). */
261 m_parent_ctxt
->replay_into (r
);
263 if (r
->errors_occurred ())
266 /* Replay this context's saved operations into r. */
267 FOR_EACH_VEC_ELT (m_mementos
, i
, m
)
269 /* Disabled low-level debugging, here if we need it: print what
271 Note that the calls to get_debug_string might lead to more
272 mementos being created for the strings.
273 This can also be used to exercise the debug_string
276 printf ("context %p replaying (%p): %s\n",
277 (void *)this, (void *)m
, m
->get_debug_string ());
281 if (r
->errors_occurred ())
286 /* During a playback, we associate objects from the recording with
287 their counterparts during this playback.
289 For simplicity, we store this within the recording objects.
291 The following method cleans away these associations, to ensure that
292 we never have out-of-date associations lingering on subsequent
293 playbacks (the objects pointed to are GC-managed, but the
294 recording objects don't own refs to them). */
297 recording::context::disassociate_from_playback ()
303 m_parent_ctxt
->disassociate_from_playback ();
305 FOR_EACH_VEC_ELT (m_mementos
, i
, m
)
307 m
->set_playback_obj (NULL
);
311 /* Create a recording::string instance and add it to this context's list
314 This creates a fresh copy of the given 0-terminated buffer. */
317 recording::context::new_string (const char *text
)
322 recording::string
*result
= new string (this, text
);
327 /* Create a recording::location instance and add it to this context's
330 Implements the post-error-checking part of
331 gcc_jit_context_new_location. */
333 recording::location
*
334 recording::context::new_location (const char *filename
,
338 recording::location
*result
=
339 new recording::location (this,
340 new_string (filename
),
346 /* If we haven't seen this enum value yet, create a recording::type
347 instance and add it to this context's list of mementos.
349 If we have seen it before, reuse our cached value, so that repeated
350 calls on the context give the same object.
352 If we have a parent context, the cache is within the ultimate
355 Implements the post-error-checking part of
356 gcc_jit_context_get_type. */
359 recording::context::get_type (enum gcc_jit_types kind
)
361 if (!m_basic_types
[kind
])
364 m_basic_types
[kind
] = m_parent_ctxt
->get_type (kind
);
367 recording::type
*result
= new memento_of_get_type (this, kind
);
369 m_basic_types
[kind
] = result
;
373 return m_basic_types
[kind
];
376 /* Get a recording::type instance for the given size and signedness.
377 This is implemented in terms of recording::context::get_type
380 Implements the post-error-checking part of
381 gcc_jit_context_get_int_type. */
384 recording::context::get_int_type (int num_bytes
, int is_signed
)
386 /* We can't use a switch here since some of the values are macros affected
387 by options; e.g. i386.h has
388 #define LONG_TYPE_SIZE (TARGET_X32 ? 32 : BITS_PER_WORD)
389 Compare with tree.c's make_or_reuse_type. Note that the _SIZE macros
390 are in bits, rather than bytes.
392 const int num_bits
= num_bytes
* 8;
393 if (num_bits
== INT_TYPE_SIZE
)
394 return get_type (is_signed
396 : GCC_JIT_TYPE_UNSIGNED_INT
);
397 if (num_bits
== CHAR_TYPE_SIZE
)
398 return get_type (is_signed
399 ? GCC_JIT_TYPE_SIGNED_CHAR
400 : GCC_JIT_TYPE_UNSIGNED_CHAR
);
401 if (num_bits
== SHORT_TYPE_SIZE
)
402 return get_type (is_signed
404 : GCC_JIT_TYPE_UNSIGNED_SHORT
);
405 if (num_bits
== LONG_TYPE_SIZE
)
406 return get_type (is_signed
408 : GCC_JIT_TYPE_UNSIGNED_LONG
);
409 if (num_bits
== LONG_LONG_TYPE_SIZE
)
410 return get_type (is_signed
411 ? GCC_JIT_TYPE_LONG_LONG
412 : GCC_JIT_TYPE_UNSIGNED_LONG_LONG
);
414 /* Some other size, not corresponding to the C int types. */
415 /* To be written: support arbitrary other sizes, sharing by
416 memoizing at the recording::context level? */
420 /* Create a recording::type instance and add it to this context's list
423 Implements the post-error-checking part of
424 gcc_jit_context_new_array_type. */
427 recording::context::new_array_type (recording::location
*loc
,
428 recording::type
*element_type
,
431 if (struct_
*s
= element_type
->dyn_cast_struct ())
432 if (!s
->get_fields ())
435 "cannot create an array of type %s"
436 " until the fields have been set",
437 s
->get_name ()->c_str ());
440 recording::type
*result
=
441 new recording::array_type (this, loc
, element_type
, num_elements
);
446 /* Create a recording::field instance and add it to this context's list
449 Implements the post-error-checking part of
450 gcc_jit_context_new_field. */
453 recording::context::new_field (recording::location
*loc
,
454 recording::type
*type
,
457 recording::field
*result
=
458 new recording::field (this, loc
, type
, new_string (name
));
463 /* Create a recording::struct_ instance and add it to this context's
464 list of mementos and list of compound types.
466 Implements the post-error-checking part of
467 gcc_jit_context_new_struct_type. */
470 recording::context::new_struct_type (recording::location
*loc
,
473 recording::struct_
*result
= new struct_ (this, loc
, new_string (name
));
475 m_compound_types
.safe_push (result
);
479 /* Create a recording::union_ instance and add it to this context's
480 list of mementos and list of compound types.
482 Implements the first post-error-checking part of
483 gcc_jit_context_new_union_type. */
486 recording::context::new_union_type (recording::location
*loc
,
489 recording::union_
*result
= new union_ (this, loc
, new_string (name
));
491 m_compound_types
.safe_push (result
);
495 /* Create a recording::function_type instance and add it to this context's
498 Used by new_function_ptr_type and by builtins_manager::make_fn_type. */
500 recording::function_type
*
501 recording::context::new_function_type (recording::type
*return_type
,
503 recording::type
**param_types
,
506 recording::function_type
*fn_type
507 = new function_type (this,
516 /* Create a recording::type instance and add it to this context's list
519 Implements the post-error-checking part of
520 gcc_jit_context_new_function_ptr_type. */
523 recording::context::new_function_ptr_type (recording::location
*, /* unused loc */
524 recording::type
*return_type
,
526 recording::type
**param_types
,
529 recording::function_type
*fn_type
530 = new_function_type (return_type
,
535 /* Return a pointer-type to the the function type. */
536 return fn_type
->get_pointer ();
539 /* Create a recording::param instance and add it to this context's list
542 Implements the post-error-checking part of
543 gcc_jit_context_new_param. */
546 recording::context::new_param (recording::location
*loc
,
547 recording::type
*type
,
550 recording::param
*result
= new recording::param (this, loc
, type
, new_string (name
));
555 /* Create a recording::function instance and add it to this context's list
556 of mementos and list of functions.
558 Implements the post-error-checking part of
559 gcc_jit_context_new_function. */
561 recording::function
*
562 recording::context::new_function (recording::location
*loc
,
563 enum gcc_jit_function_kind kind
,
564 recording::type
*return_type
,
567 recording::param
**params
,
569 enum built_in_function builtin_id
)
571 recording::function
*result
=
572 new recording::function (this,
573 loc
, kind
, return_type
,
575 num_params
, params
, is_variadic
,
578 m_functions
.safe_push (result
);
583 /* Locate the builtins_manager (if any) for this family of contexts,
584 creating it if it doesn't exist already.
586 All of the recording contexts in a family share one builtins_manager:
587 if we have a child context, follow the parent links to get the
588 ultimate ancestor context, and look for it/store it there. */
591 recording::context::get_builtins_manager ()
594 return m_parent_ctxt
->get_builtins_manager ();
596 if (!m_builtins_manager
)
597 m_builtins_manager
= new builtins_manager (this);
599 return m_builtins_manager
;
602 /* Get a recording::function instance, which is lazily-created and added
603 to the context's lists of mementos.
605 Implements the post-error-checking part of
606 gcc_jit_context_get_builtin_function. */
608 recording::function
*
609 recording::context::get_builtin_function (const char *name
)
611 builtins_manager
*bm
= get_builtins_manager ();
612 return bm
->get_builtin_function (name
);
615 /* Create a recording::global instance and add it to this context's list
618 Implements the post-error-checking part of
619 gcc_jit_context_new_global. */
622 recording::context::new_global (recording::location
*loc
,
623 recording::type
*type
,
626 recording::lvalue
*result
=
627 new recording::global (this, loc
, type
, new_string (name
));
632 /* Create a recording::memento_of_new_rvalue_from_int instance and add
633 it to this context's list of mementos.
635 Implements the post-error-checking part of
636 gcc_jit_context_new_rvalue_from_int. */
639 recording::context::new_rvalue_from_int (recording::type
*type
,
642 recording::rvalue
*result
=
643 new memento_of_new_rvalue_from_int (this, NULL
, type
, value
);
648 /* Create a recording::memento_of_new_rvalue_from_double instance and
649 add it to this context's list of mementos.
651 Implements the post-error-checking part of
652 gcc_jit_context_new_rvalue_from_double. */
655 recording::context::new_rvalue_from_double (recording::type
*type
,
658 recording::rvalue
*result
=
659 new memento_of_new_rvalue_from_double (this, NULL
, type
, value
);
664 /* Create a recording::memento_of_new_rvalue_from_ptr instance and add
665 it to this context's list of mementos.
667 Implements the post-error-checking part of
668 gcc_jit_context_new_rvalue_from_ptr. */
671 recording::context::new_rvalue_from_ptr (recording::type
*type
,
674 recording::rvalue
*result
=
675 new memento_of_new_rvalue_from_ptr (this, NULL
, type
, value
);
680 /* Create a recording::memento_of_new_string_literal instance and add it
681 to this context's list of mementos.
683 Implements the post-error-checking part of
684 gcc_jit_context_new_string_literal. */
687 recording::context::new_string_literal (const char *value
)
689 recording::rvalue
*result
=
690 new memento_of_new_string_literal (this, NULL
, new_string (value
));
695 /* Create a recording::unary_op instance and add it to this context's
698 Implements the post-error-checking part of
699 gcc_jit_context_new_unary_op. */
702 recording::context::new_unary_op (recording::location
*loc
,
703 enum gcc_jit_unary_op op
,
704 recording::type
*result_type
,
705 recording::rvalue
*a
)
707 recording::rvalue
*result
=
708 new unary_op (this, loc
, op
, result_type
, a
);
713 /* Create a recording::binary_op instance and add it to this context's
716 Implements the post-error-checking part of
717 gcc_jit_context_new_binary_op. */
720 recording::context::new_binary_op (recording::location
*loc
,
721 enum gcc_jit_binary_op op
,
722 recording::type
*result_type
,
723 recording::rvalue
*a
,
724 recording::rvalue
*b
)
726 recording::rvalue
*result
=
727 new binary_op (this, loc
, op
, result_type
, a
, b
);
732 /* Create a recording::comparison instance and add it to this context's
735 Implements the post-error-checking part of
736 gcc_jit_context_new_comparison. */
739 recording::context::new_comparison (recording::location
*loc
,
740 enum gcc_jit_comparison op
,
741 recording::rvalue
*a
,
742 recording::rvalue
*b
)
744 recording::rvalue
*result
= new comparison (this, loc
, op
, a
, b
);
749 /* Create a recording::cast instance and add it to this context's list
752 Implements the post-error-checking part of
753 gcc_jit_context_new_cast. */
756 recording::context::new_cast (recording::location
*loc
,
757 recording::rvalue
*expr
,
758 recording::type
*type_
)
760 recording::rvalue
*result
= new cast (this, loc
, expr
, type_
);
765 /* Create a recording::call instance and add it to this context's list
768 Implements the post-error-checking part of
769 gcc_jit_context_new_call. */
772 recording::context::new_call (recording::location
*loc
,
774 int numargs
, recording::rvalue
**args
)
776 recording::rvalue
*result
= new call (this, loc
, func
, numargs
, args
);
781 /* Create a recording::call_through_ptr instance and add it to this
782 context's list of mementos.
784 Implements the post-error-checking part of
785 gcc_jit_context_new_call_through_ptr. */
788 recording::context::new_call_through_ptr (recording::location
*loc
,
789 recording::rvalue
*fn_ptr
,
791 recording::rvalue
**args
)
793 recording::rvalue
*result
= new call_through_ptr (this, loc
, fn_ptr
, numargs
, args
);
798 /* Create a recording::array_access instance and add it to this context's list
801 Implements the post-error-checking part of
802 gcc_jit_context_new_array_access. */
805 recording::context::new_array_access (recording::location
*loc
,
806 recording::rvalue
*ptr
,
807 recording::rvalue
*index
)
809 recording::lvalue
*result
= new array_access (this, loc
, ptr
, index
);
814 /* Set the given string option for this context, or add an error if
817 Implements the post-error-checking part of
818 gcc_jit_context_set_str_option. */
821 recording::context::set_str_option (enum gcc_jit_str_option opt
,
824 if (opt
< 0 || opt
>= GCC_JIT_NUM_STR_OPTIONS
)
827 "unrecognized (enum gcc_jit_str_option) value: %i", opt
);
830 m_str_options
[opt
] = value
;
833 /* Set the given integer option for this context, or add an error if
836 Implements the post-error-checking part of
837 gcc_jit_context_set_int_option. */
840 recording::context::set_int_option (enum gcc_jit_int_option opt
,
843 if (opt
< 0 || opt
>= GCC_JIT_NUM_INT_OPTIONS
)
846 "unrecognized (enum gcc_jit_int_option) value: %i", opt
);
849 m_int_options
[opt
] = value
;
852 /* Set the given boolean option for this context, or add an error if
855 Implements the post-error-checking part of
856 gcc_jit_context_set_bool_option. */
859 recording::context::set_bool_option (enum gcc_jit_bool_option opt
,
862 if (opt
< 0 || opt
>= GCC_JIT_NUM_BOOL_OPTIONS
)
865 "unrecognized (enum gcc_jit_bool_option) value: %i", opt
);
868 m_bool_options
[opt
] = value
? true : false;
871 /* This mutex guards gcc::jit::recording::context::compile, so that only
872 one thread can be accessing the bulk of GCC's state at once. */
874 static pthread_mutex_t jit_mutex
= PTHREAD_MUTEX_INITIALIZER
;
876 /* Validate this context, and if it passes, compile it within a
879 Implements the post-error-checking part of
880 gcc_jit_context_compile. */
883 recording::context::compile ()
887 if (errors_occurred ())
890 /* Acquire the big GCC mutex. */
891 pthread_mutex_lock (&jit_mutex
);
892 gcc_assert (NULL
== ::gcc::jit::active_playback_ctxt
);
894 /* Set up a playback context. */
895 ::gcc::jit::playback::context
replayer (this);
896 ::gcc::jit::active_playback_ctxt
= &replayer
;
898 result
*result_obj
= replayer
.compile ();
900 /* Release the big GCC mutex. */
901 ::gcc::jit::active_playback_ctxt
= NULL
;
902 pthread_mutex_unlock (&jit_mutex
);
907 /* Format the given error using printf's conventions, print
908 it to stderr, and add it to the context. */
911 recording::context::add_error (location
*loc
, const char *fmt
, ...)
915 add_error_va (loc
, fmt
, ap
);
919 /* Format the given error using printf's conventions, print
920 it to stderr, and add it to the context. */
923 recording::context::add_error_va (location
*loc
, const char *fmt
, va_list ap
)
929 vasprintf (&malloced_msg
, fmt
, ap
);
932 errmsg
= malloced_msg
;
933 has_ownership
= true;
937 errmsg
= "out of memory generating error message";
938 has_ownership
= false;
941 const char *ctxt_progname
=
942 get_str_option (GCC_JIT_STR_OPTION_PROGNAME
);
944 ctxt_progname
= "libgccjit.so";
947 fprintf (stderr
, "%s: %s: error: %s\n",
949 loc
->get_debug_string (),
952 fprintf (stderr
, "%s: error: %s\n",
958 m_first_error_str
= const_cast <char *> (errmsg
);
959 m_owns_first_error_str
= has_ownership
;
968 /* Get the message for the first error that occurred on this context, or
969 NULL if no errors have occurred on it.
971 Implements the post-error-checking part of
972 gcc_jit_context_get_first_error. */
975 recording::context::get_first_error () const
977 return m_first_error_str
;
980 /* Lazily generate and record a recording::type representing an opaque
983 For use if client code tries to dereference the result of
984 get_type (GCC_JIT_TYPE_FILE_PTR). */
987 recording::context::get_opaque_FILE_type ()
990 m_FILE_type
= new_struct_type (NULL
, "FILE");
994 /* Dump a C-like representation of the given context to the given path.
995 If UPDATE_LOCATIONS is true, update the locations within the
996 context's mementos to point to the dumpfile.
998 Implements the post-error-checking part of
999 gcc_jit_context_dump_to_file. */
1002 recording::context::dump_to_file (const char *path
, bool update_locations
)
1005 dump
d (*this, path
, update_locations
);
1007 /* Forward declaration of structs and unions. */
1009 FOR_EACH_VEC_ELT (m_compound_types
, i
, st
)
1011 d
.write ("%s;\n\n", st
->get_debug_string ());
1014 /* Content of structs, where set. */
1015 FOR_EACH_VEC_ELT (m_compound_types
, i
, st
)
1016 if (st
->get_fields ())
1018 st
->get_fields ()->write_to_dump (d
);
1023 FOR_EACH_VEC_ELT (m_functions
, i
, fn
)
1025 fn
->write_to_dump (d
);
1029 /* This is a pre-compilation check for the context (and any parents).
1031 Detect errors within the context, adding errors if any are found. */
1034 recording::context::validate ()
1037 m_parent_ctxt
->validate ();
1041 FOR_EACH_VEC_ELT (m_functions
, i
, fn
)
1045 /* The implementation of class gcc::jit::recording::memento. */
1047 /* Get a (const char *) debug description of the given memento, by
1048 calling the pure-virtual make_debug_string hook, caching the
1051 It is intended that this should only be called in debugging and
1052 error-handling paths, so this doesn't need to be particularly
1056 recording::memento::get_debug_string ()
1058 if (!m_debug_string
)
1059 m_debug_string
= make_debug_string ();
1060 return m_debug_string
->c_str ();
1063 /* Default implementation of recording::memento::write_to_dump, writing
1064 an indented form of the memento's debug string to the dump. */
1067 recording::memento::write_to_dump (dump
&d
)
1069 d
.write(" %s\n", get_debug_string ());
1072 /* The implementation of class gcc::jit::recording::string. */
1074 /* Constructor for gcc::jit::recording::string::string, allocating a
1075 copy of the given text using new char[]. */
1077 recording::string::string (context
*ctxt
, const char *text
)
1080 m_len
= strlen (text
);
1081 m_buffer
= new char[m_len
+ 1];
1082 strcpy (m_buffer
, text
);
1085 /* Destructor for gcc::jit::recording::string::string. */
1087 recording::string::~string ()
1092 /* Function for making gcc::jit::recording::string instances on a
1093 context via printf-style formatting.
1095 It is intended that this should only be called in debugging and
1096 error-handling paths, so this doesn't need to be particularly
1097 optimized, hence the double-copy of the string is acceptable. */
1100 recording::string::from_printf (context
*ctxt
, const char *fmt
, ...)
1104 recording::string
*result
;
1107 vasprintf (&buf
, fmt
, ap
);
1112 ctxt
->add_error (NULL
, "malloc failure");
1116 result
= ctxt
->new_string (buf
);
1121 /* Implementation of recording::memento::make_debug_string for strings,
1122 wrapping the given string in quotes and escaping as necessary. */
1125 recording::string::make_debug_string ()
1127 /* Hack to avoid infinite recursion into strings when logging all
1128 mementos: don't re-escape strings: */
1129 if (m_buffer
[0] == '"')
1132 /* Wrap in quotes and do escaping etc */
1134 size_t sz
= (1 /* opening quote */
1135 + (m_len
* 2) /* each char might get escaped */
1136 + 1 /* closing quote */
1137 + 1); /* nil termintator */
1138 char *tmp
= new char[sz
];
1141 #define APPEND(CH) do { gcc_assert (len < sz); tmp[len++] = (CH); } while (0)
1142 APPEND('"'); /* opening quote */
1143 for (size_t i
= 0; i
< m_len
; i
++)
1145 char ch
= m_buffer
[i
];
1146 if (ch
== '\t' || ch
== '\n' || ch
== '\\' || ch
== '"')
1150 APPEND('"'); /* closing quote */
1152 tmp
[len
] = '\0'; /* nil termintator */
1154 string
*result
= m_ctxt
->new_string (tmp
);
1160 /* The implementation of class gcc::jit::recording::location. */
1162 /* Implementation of recording::memento::replay_into for locations.
1164 Create a new playback::location and store it into the
1165 recording::location's m_playback_obj field. */
1168 recording::location::replay_into (replayer
*r
)
1170 m_playback_obj
= r
->new_location (this,
1171 m_filename
->c_str (),
1176 /* Implementation of recording::memento::make_debug_string for locations,
1177 turning them into the usual form:
1178 FILENAME:LINE:COLUMN
1179 like we do when emitting diagnostics. */
1182 recording::location::make_debug_string ()
1184 return string::from_printf (m_ctxt
,
1186 m_filename
->c_str (), m_line
, m_column
);
1189 /* The implementation of class gcc::jit::recording::type. */
1191 /* Given a type T, get the type T*.
1193 If this doesn't already exist, generate a new memento_of_get_pointer
1194 instance and add it to this type's context's list of mementos.
1196 Otherwise, use the cached type.
1198 Implements the post-error-checking part of
1199 gcc_jit_type_get_pointer. */
1202 recording::type::get_pointer ()
1204 if (!m_pointer_to_this_type
)
1206 m_pointer_to_this_type
= new memento_of_get_pointer (this);
1207 m_ctxt
->record (m_pointer_to_this_type
);
1209 return m_pointer_to_this_type
;
1212 /* Given a type T, get the type const T.
1214 Implements the post-error-checking part of
1215 gcc_jit_type_get_const. */
1218 recording::type::get_const ()
1220 recording::type
*result
= new memento_of_get_const (this);
1221 m_ctxt
->record (result
);
1225 /* Given a type T, get the type volatile T.
1227 Implements the post-error-checking part of
1228 gcc_jit_type_get_volatile. */
1231 recording::type::get_volatile ()
1233 recording::type
*result
= new memento_of_get_volatile (this);
1234 m_ctxt
->record (result
);
1238 /* Implementation of pure virtual hook recording::type::dereference for
1239 recording::memento_of_get_type. */
1242 recording::memento_of_get_type::dereference ()
1246 default: gcc_unreachable ();
1248 case GCC_JIT_TYPE_VOID
:
1251 case GCC_JIT_TYPE_VOID_PTR
:
1252 return m_ctxt
->get_type (GCC_JIT_TYPE_VOID
);
1254 case GCC_JIT_TYPE_BOOL
:
1255 case GCC_JIT_TYPE_CHAR
:
1256 case GCC_JIT_TYPE_SIGNED_CHAR
:
1257 case GCC_JIT_TYPE_UNSIGNED_CHAR
:
1258 case GCC_JIT_TYPE_SHORT
:
1259 case GCC_JIT_TYPE_UNSIGNED_SHORT
:
1260 case GCC_JIT_TYPE_INT
:
1261 case GCC_JIT_TYPE_UNSIGNED_INT
:
1262 case GCC_JIT_TYPE_LONG
:
1263 case GCC_JIT_TYPE_UNSIGNED_LONG
:
1264 case GCC_JIT_TYPE_LONG_LONG
:
1265 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG
:
1266 case GCC_JIT_TYPE_FLOAT
:
1267 case GCC_JIT_TYPE_DOUBLE
:
1268 case GCC_JIT_TYPE_LONG_DOUBLE
:
1269 case GCC_JIT_TYPE_COMPLEX_FLOAT
:
1270 case GCC_JIT_TYPE_COMPLEX_DOUBLE
:
1271 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE
:
1272 /* Not a pointer: */
1275 case GCC_JIT_TYPE_CONST_CHAR_PTR
:
1276 return m_ctxt
->get_type (GCC_JIT_TYPE_CHAR
)->get_const ();
1278 case GCC_JIT_TYPE_SIZE_T
:
1279 /* Not a pointer: */
1282 case GCC_JIT_TYPE_FILE_PTR
:
1283 /* Give the client code back an opaque "struct FILE". */
1284 return m_ctxt
->get_opaque_FILE_type ();
1288 /* Implementation of pure virtual hook recording::type::is_int for
1289 recording::memento_of_get_type. */
1292 recording::memento_of_get_type::is_int () const
1296 default: gcc_unreachable ();
1298 case GCC_JIT_TYPE_VOID
:
1301 case GCC_JIT_TYPE_VOID_PTR
:
1304 case GCC_JIT_TYPE_BOOL
:
1307 case GCC_JIT_TYPE_CHAR
:
1308 case GCC_JIT_TYPE_SIGNED_CHAR
:
1309 case GCC_JIT_TYPE_UNSIGNED_CHAR
:
1310 case GCC_JIT_TYPE_SHORT
:
1311 case GCC_JIT_TYPE_UNSIGNED_SHORT
:
1312 case GCC_JIT_TYPE_INT
:
1313 case GCC_JIT_TYPE_UNSIGNED_INT
:
1314 case GCC_JIT_TYPE_LONG
:
1315 case GCC_JIT_TYPE_UNSIGNED_LONG
:
1316 case GCC_JIT_TYPE_LONG_LONG
:
1317 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG
:
1320 case GCC_JIT_TYPE_FLOAT
:
1321 case GCC_JIT_TYPE_DOUBLE
:
1322 case GCC_JIT_TYPE_LONG_DOUBLE
:
1325 case GCC_JIT_TYPE_CONST_CHAR_PTR
:
1328 case GCC_JIT_TYPE_SIZE_T
:
1331 case GCC_JIT_TYPE_FILE_PTR
:
1334 case GCC_JIT_TYPE_COMPLEX_FLOAT
:
1335 case GCC_JIT_TYPE_COMPLEX_DOUBLE
:
1336 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE
:
1341 /* Implementation of pure virtual hook recording::type::is_float for
1342 recording::memento_of_get_type. */
1345 recording::memento_of_get_type::is_float () const
1349 default: gcc_unreachable ();
1351 case GCC_JIT_TYPE_VOID
:
1354 case GCC_JIT_TYPE_VOID_PTR
:
1357 case GCC_JIT_TYPE_BOOL
:
1360 case GCC_JIT_TYPE_CHAR
:
1361 case GCC_JIT_TYPE_SIGNED_CHAR
:
1362 case GCC_JIT_TYPE_UNSIGNED_CHAR
:
1363 case GCC_JIT_TYPE_SHORT
:
1364 case GCC_JIT_TYPE_UNSIGNED_SHORT
:
1365 case GCC_JIT_TYPE_INT
:
1366 case GCC_JIT_TYPE_UNSIGNED_INT
:
1367 case GCC_JIT_TYPE_LONG
:
1368 case GCC_JIT_TYPE_UNSIGNED_LONG
:
1369 case GCC_JIT_TYPE_LONG_LONG
:
1370 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG
:
1373 case GCC_JIT_TYPE_FLOAT
:
1374 case GCC_JIT_TYPE_DOUBLE
:
1375 case GCC_JIT_TYPE_LONG_DOUBLE
:
1378 case GCC_JIT_TYPE_CONST_CHAR_PTR
:
1381 case GCC_JIT_TYPE_SIZE_T
:
1384 case GCC_JIT_TYPE_FILE_PTR
:
1387 case GCC_JIT_TYPE_COMPLEX_FLOAT
:
1388 case GCC_JIT_TYPE_COMPLEX_DOUBLE
:
1389 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE
:
1394 /* Implementation of pure virtual hook recording::type::is_bool for
1395 recording::memento_of_get_type. */
1398 recording::memento_of_get_type::is_bool () const
1402 default: gcc_unreachable ();
1404 case GCC_JIT_TYPE_VOID
:
1407 case GCC_JIT_TYPE_VOID_PTR
:
1410 case GCC_JIT_TYPE_BOOL
:
1413 case GCC_JIT_TYPE_CHAR
:
1414 case GCC_JIT_TYPE_SIGNED_CHAR
:
1415 case GCC_JIT_TYPE_UNSIGNED_CHAR
:
1416 case GCC_JIT_TYPE_SHORT
:
1417 case GCC_JIT_TYPE_UNSIGNED_SHORT
:
1418 case GCC_JIT_TYPE_INT
:
1419 case GCC_JIT_TYPE_UNSIGNED_INT
:
1420 case GCC_JIT_TYPE_LONG
:
1421 case GCC_JIT_TYPE_UNSIGNED_LONG
:
1422 case GCC_JIT_TYPE_LONG_LONG
:
1423 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG
:
1426 case GCC_JIT_TYPE_FLOAT
:
1427 case GCC_JIT_TYPE_DOUBLE
:
1428 case GCC_JIT_TYPE_LONG_DOUBLE
:
1431 case GCC_JIT_TYPE_CONST_CHAR_PTR
:
1434 case GCC_JIT_TYPE_SIZE_T
:
1437 case GCC_JIT_TYPE_FILE_PTR
:
1440 case GCC_JIT_TYPE_COMPLEX_FLOAT
:
1441 case GCC_JIT_TYPE_COMPLEX_DOUBLE
:
1442 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE
:
1447 /* Implementation of pure virtual hook recording::memento::replay_into
1448 for recording::memento_of_get_type. */
1451 recording::memento_of_get_type::replay_into (replayer
*r
)
1453 set_playback_obj (r
->get_type (m_kind
));
1456 /* The implementation of class gcc::jit::recording::memento_of_get_type. */
1458 /* Descriptive strings for each of enum gcc_jit_types. */
1460 static const char * const get_type_strings
[] = {
1461 "void", /* GCC_JIT_TYPE_VOID */
1462 "void *", /* GCC_JIT_TYPE_VOID_PTR */
1464 "bool", /* GCC_JIT_TYPE_BOOL */
1466 "char", /* GCC_JIT_TYPE_CHAR */
1467 "signed char", /* GCC_JIT_TYPE_SIGNED_CHAR */
1468 "unsigned char", /* GCC_JIT_TYPE_UNSIGNED_CHAR */
1470 "short", /* GCC_JIT_TYPE_SHORT */
1471 "unsigned short", /* GCC_JIT_TYPE_UNSIGNED_SHORT */
1473 "int", /* GCC_JIT_TYPE_INT */
1474 "unsigned int", /* GCC_JIT_TYPE_UNSIGNED_INT */
1476 "long", /* GCC_JIT_TYPE_LONG */
1477 "unsigned long", /* GCC_JIT_TYPE_UNSIGNED_LONG, */
1479 "long long", /* GCC_JIT_TYPE_LONG_LONG */
1480 "unsigned long long", /* GCC_JIT_TYPE_UNSIGNED_LONG_LONG */
1482 "float", /* GCC_JIT_TYPE_FLOAT */
1483 "double", /* GCC_JIT_TYPE_DOUBLE */
1484 "long double", /* GCC_JIT_TYPE_LONG_DOUBLE */
1486 "const char *", /* GCC_JIT_TYPE_CONST_CHAR_PTR */
1488 "size_t", /* GCC_JIT_TYPE_SIZE_T */
1490 "FILE *", /* GCC_JIT_TYPE_FILE_PTR */
1492 "complex float", /* GCC_JIT_TYPE_COMPLEX_FLOAT */
1493 "complex double", /* GCC_JIT_TYPE_COMPLEX_DOUBLE */
1494 "complex long double" /* GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE */
1498 /* Implementation of recording::memento::make_debug_string for
1499 results of get_type, using a simple table of type names. */
1502 recording::memento_of_get_type::make_debug_string ()
1504 return m_ctxt
->new_string (get_type_strings
[m_kind
]);
1507 /* The implementation of class gcc::jit::recording::memento_of_get_pointer. */
1509 /* Override of default implementation of
1510 recording::type::accepts_writes_from for get_pointer.
1512 Require a pointer type, and allowing writes to
1513 (const T *) from a (T*), but not the other way around. */
1516 recording::memento_of_get_pointer::accepts_writes_from (type
*rtype
)
1518 /* Must be a pointer type: */
1519 type
*rtype_points_to
= rtype
->is_pointer ();
1520 if (!rtype_points_to
)
1523 /* It's OK to assign to a (const T *) from a (T *). */
1524 return m_other_type
->unqualified ()
1525 ->accepts_writes_from (rtype_points_to
);
1528 /* Implementation of pure virtual hook recording::memento::replay_into
1529 for recording::memento_of_get_pointer. */
1532 recording::memento_of_get_pointer::replay_into (replayer
*)
1534 set_playback_obj (m_other_type
->playback_type ()->get_pointer ());
1537 /* Implementation of recording::memento::make_debug_string for
1538 results of get_pointer, adding " *" to the underlying type,
1539 with special-casing to handle function pointer types. */
1542 recording::memento_of_get_pointer::make_debug_string ()
1544 /* Special-case function pointer types, to put the "*" in parens between
1545 the return type and the params (for one level of dereferencing, at
1547 if (function_type
*fn_type
= m_other_type
->dyn_cast_function_type ())
1548 return fn_type
->make_debug_string_with_ptr ();
1550 return string::from_printf (m_ctxt
,
1551 "%s *", m_other_type
->get_debug_string ());
1554 /* The implementation of class gcc::jit::recording::memento_of_get_const. */
1556 /* Implementation of pure virtual hook recording::memento::replay_into
1557 for recording::memento_of_get_const. */
1560 recording::memento_of_get_const::replay_into (replayer
*)
1562 set_playback_obj (m_other_type
->playback_type ()->get_const ());
1565 /* Implementation of recording::memento::make_debug_string for
1566 results of get_const, prepending "const ". */
1569 recording::memento_of_get_const::make_debug_string ()
1571 return string::from_printf (m_ctxt
,
1572 "const %s", m_other_type
->get_debug_string ());
1575 /* The implementation of class gcc::jit::recording::memento_of_get_volatile. */
1577 /* Implementation of pure virtual hook recording::memento::replay_into
1578 for recording::memento_of_get_volatile. */
1581 recording::memento_of_get_volatile::replay_into (replayer
*)
1583 set_playback_obj (m_other_type
->playback_type ()->get_volatile ());
1586 /* Implementation of recording::memento::make_debug_string for
1587 results of get_volatile, prepending "volatile ". */
1590 recording::memento_of_get_volatile::make_debug_string ()
1592 return string::from_printf (m_ctxt
,
1593 "volatile %s", m_other_type
->get_debug_string ());
1596 /* The implementation of class gcc::jit::recording::array_type */
1598 /* Implementation of pure virtual hook recording::type::dereference for
1599 recording::array_type. */
1602 recording::array_type::dereference ()
1604 return m_element_type
;
1607 /* Implementation of pure virtual hook recording::memento::replay_into
1608 for recording::array_type. */
1611 recording::array_type::replay_into (replayer
*r
)
1613 set_playback_obj (r
->new_array_type (playback_location (r
, m_loc
),
1614 m_element_type
->playback_type (),
1618 /* Implementation of recording::memento::make_debug_string for
1619 results of new_array_type. */
1622 recording::array_type::make_debug_string ()
1624 return string::from_printf (m_ctxt
,
1626 m_element_type
->get_debug_string (),
1630 /* The implementation of class gcc::jit::recording::function_type */
1632 /* Constructor for gcc::jit::recording::function_type. */
1634 recording::function_type::function_type (context
*ctxt
,
1640 m_return_type (return_type
),
1642 m_is_variadic (is_variadic
)
1644 for (int i
= 0; i
< num_params
; i
++)
1645 m_param_types
.safe_push (param_types
[i
]);
1648 /* Implementation of pure virtual hook recording::type::dereference for
1649 recording::function_type. */
1652 recording::function_type::dereference ()
1657 /* Implementation of pure virtual hook recording::memento::replay_into
1658 for recording::function_type. */
1661 recording::function_type::replay_into (replayer
*r
)
1663 /* Convert m_param_types to a vec of playback type. */
1664 auto_vec
<playback::type
*> param_types
;
1666 recording::type
*type
;
1667 param_types
.create (m_param_types
.length ());
1668 FOR_EACH_VEC_ELT (m_param_types
, i
, type
)
1669 param_types
.safe_push (type
->playback_type ());
1671 set_playback_obj (r
->new_function_type (m_return_type
->playback_type (),
1676 /* Special-casing for make_debug_string for get_pointer results for
1677 handling (one level) of pointers to functions. */
1680 recording::function_type::make_debug_string_with_ptr ()
1682 return make_debug_string_with ("(*) ");
1685 /* Implementation of recording::memento::make_debug_string for
1686 results of new_function_type. */
1689 recording::function_type::make_debug_string ()
1691 return make_debug_string_with ("");
1694 /* Build a debug string representation of the form:
1696 RESULT_TYPE INSERT (PARAM_TYPES)
1698 for use when handling 0 and 1 level of indirection to this
1702 recording::function_type::make_debug_string_with (const char *insert
)
1704 /* First, build a buffer for the arguments. */
1705 /* Calculate length of said buffer. */
1706 size_t sz
= 1; /* nil terminator */
1707 for (unsigned i
= 0; i
< m_param_types
.length (); i
++)
1709 sz
+= strlen (m_param_types
[i
]->get_debug_string ());
1710 sz
+= 2; /* ", " separator */
1713 sz
+= 5; /* ", ..." separator and ellipsis */
1715 /* Now allocate and populate the buffer. */
1716 char *argbuf
= new char[sz
];
1719 for (unsigned i
= 0; i
< m_param_types
.length (); i
++)
1721 strcpy (argbuf
+ len
, m_param_types
[i
]->get_debug_string ());
1722 len
+= strlen (m_param_types
[i
]->get_debug_string ());
1723 if (i
+ 1 < m_param_types
.length ())
1725 strcpy (argbuf
+ len
, ", ");
1731 if (m_param_types
.length ())
1733 strcpy (argbuf
+ len
, ", ");
1736 strcpy (argbuf
+ len
, "...");
1741 /* ...and use it to get the string for the call as a whole. */
1742 string
*result
= string::from_printf (m_ctxt
,
1744 m_return_type
->get_debug_string (),
1753 /* The implementation of class gcc::jit::recording::field. */
1755 /* Implementation of pure virtual hook recording::memento::replay_into
1756 for recording::field. */
1759 recording::field::replay_into (replayer
*r
)
1761 set_playback_obj (r
->new_field (playback_location (r
, m_loc
),
1762 m_type
->playback_type (),
1763 playback_string (m_name
)));
1766 /* Override the default implementation of
1767 recording::memento::write_to_dump. Dump each field
1768 by dumping a line of the form:
1770 so that we can build up a struct/union field-byfield. */
1773 recording::field::write_to_dump (dump
&d
)
1775 d
.write (" %s %s;\n",
1776 m_type
->get_debug_string (),
1780 /* Implementation of recording::memento::make_debug_string for
1781 results of new_field. */
1784 recording::field::make_debug_string ()
1789 /* The implementation of class gcc::jit::recording::compound_type */
1791 /* The constructor for gcc::jit::recording::compound_type. */
1793 recording::compound_type::compound_type (context
*ctxt
,
1803 /* Set the fields of a compound type.
1805 Implements the post-error-checking part of
1806 gcc_jit_struct_set_fields, and is also used by
1807 gcc_jit_context_new_union_type. */
1810 recording::compound_type::set_fields (location
*loc
,
1812 field
**field_array
)
1815 gcc_assert (NULL
== m_fields
);
1817 m_fields
= new fields (this, num_fields
, field_array
);
1818 m_ctxt
->record (m_fields
);
1821 /* Implementation of pure virtual hook recording::type::dereference for
1822 recording::compound_type. */
1825 recording::compound_type::dereference ()
1827 return NULL
; /* not a pointer */
1830 /* The implementation of class gcc::jit::recording::struct_. */
1832 /* The constructor for gcc::jit::recording::struct_. */
1834 recording::struct_::struct_ (context
*ctxt
,
1837 : compound_type (ctxt
, loc
, name
)
1841 /* Implementation of pure virtual hook recording::memento::replay_into
1842 for recording::struct_. */
1845 recording::struct_::replay_into (replayer
*r
)
1848 r
->new_compound_type (playback_location (r
, get_loc ()),
1849 get_name ()->c_str (),
1850 true /* is_struct */));
1853 /* Implementation of recording::memento::make_debug_string for
1857 recording::struct_::make_debug_string ()
1859 return string::from_printf (m_ctxt
,
1860 "struct %s", get_name ()->c_str ());
1863 /* The implementation of class gcc::jit::recording::union_. */
1865 /* The constructor for gcc::jit::recording::union_. */
1867 recording::union_::union_ (context
*ctxt
,
1870 : compound_type (ctxt
, loc
, name
)
1874 /* Implementation of pure virtual hook recording::memento::replay_into
1875 for recording::union_. */
1878 recording::union_::replay_into (replayer
*r
)
1881 r
->new_compound_type (playback_location (r
, get_loc ()),
1882 get_name ()->c_str (),
1883 false /* is_struct */));
1886 /* Implementation of recording::memento::make_debug_string for
1890 recording::union_::make_debug_string ()
1892 return string::from_printf (m_ctxt
,
1893 "union %s", get_name ()->c_str ());
1896 /* The implementation of class gcc::jit::recording::fields. */
1898 /* The constructor for gcc::jit::recording::fields. */
1900 recording::fields::fields (compound_type
*struct_or_union
,
1903 : memento (struct_or_union
->m_ctxt
),
1904 m_struct_or_union (struct_or_union
),
1907 for (int i
= 0; i
< num_fields
; i
++)
1909 gcc_assert (fields
[i
]->get_container () == NULL
);
1910 fields
[i
]->set_container (m_struct_or_union
);
1911 m_fields
.safe_push (fields
[i
]);
1915 /* Implementation of pure virtual hook recording::memento::replay_into
1916 for recording::fields. */
1919 recording::fields::replay_into (replayer
*)
1921 auto_vec
<playback::field
*> playback_fields
;
1922 playback_fields
.create (m_fields
.length ());
1923 for (unsigned i
= 0; i
< m_fields
.length (); i
++)
1924 playback_fields
.safe_push (m_fields
[i
]->playback_field ());
1925 m_struct_or_union
->playback_compound_type ()->set_fields (&playback_fields
);
1928 /* Override the default implementation of
1929 recording::memento::write_to_dump by writing a union/struct
1930 declaration of this form:
1942 recording::fields::write_to_dump (dump
&d
)
1947 d
.write ("%s\n{\n", m_struct_or_union
->get_debug_string ());
1948 FOR_EACH_VEC_ELT (m_fields
, i
, f
)
1949 f
->write_to_dump (d
);
1953 /* Implementation of recording::memento::make_debug_string for
1957 recording::fields::make_debug_string ()
1959 return string::from_printf (m_ctxt
,
1963 /* The implementation of class gcc::jit::recording::rvalue. */
1965 /* Create a recording::access_field_rvalue instance and add it to
1966 the rvalue's context's list of mementos.
1968 Implements the post-error-checking part of
1969 gcc_jit_rvalue_access_field. */
1972 recording::rvalue::access_field (recording::location
*loc
,
1975 recording::rvalue
*result
=
1976 new access_field_rvalue (m_ctxt
, loc
, this, field
);
1977 m_ctxt
->record (result
);
1981 /* Create a recording::dereference_field_rvalue instance and add it to
1982 the rvalue's context's list of mementos.
1984 Implements the post-error-checking part of
1985 gcc_jit_rvalue_dereference_field. */
1988 recording::rvalue::dereference_field (recording::location
*loc
,
1991 recording::lvalue
*result
=
1992 new dereference_field_rvalue (m_ctxt
, loc
, this, field
);
1993 m_ctxt
->record (result
);
1997 /* Create a recording::dereference_rvalue instance and add it to the
1998 rvalue's context's list of mementos.
2000 Implements the post-error-checking part of
2001 gcc_jit_rvalue_dereference. */
2004 recording::rvalue::dereference (recording::location
*loc
)
2006 recording::lvalue
*result
=
2007 new dereference_rvalue (m_ctxt
, loc
, this);
2008 m_ctxt
->record (result
);
2012 /* The implementation of class gcc::jit::recording::lvalue. */
2014 /* Create a recording::new_access_field_of_lvalue instance and add it to
2015 the lvalue's context's list of mementos.
2017 Implements the post-error-checking part of
2018 gcc_jit_lvalue_access_field. */
2021 recording::lvalue::access_field (recording::location
*loc
,
2024 recording::lvalue
*result
=
2025 new access_field_of_lvalue (m_ctxt
, loc
, this, field
);
2026 m_ctxt
->record (result
);
2030 /* Create a recording::get_address_of_lvalue instance and add it to
2031 the lvalue's context's list of mementos.
2033 Implements the post-error-checking part of
2034 gcc_jit_lvalue_get_address. */
2037 recording::lvalue::get_address (recording::location
*loc
)
2039 recording::rvalue
*result
=
2040 new get_address_of_lvalue (m_ctxt
, loc
, this);
2041 m_ctxt
->record (result
);
2045 /* The implementation of class gcc::jit::recording::param. */
2047 /* Implementation of pure virtual hook recording::memento::replay_into
2048 for recording::param. */
2051 recording::param::replay_into (replayer
*r
)
2053 set_playback_obj (r
->new_param (playback_location (r
, m_loc
),
2054 m_type
->playback_type (),
2059 /* The implementation of class gcc::jit::recording::function. */
2061 /* gcc::jit::recording::function's constructor. */
2063 recording::function::function (context
*ctxt
,
2064 recording::location
*loc
,
2065 enum gcc_jit_function_kind kind
,
2067 recording::string
*name
,
2069 recording::param
**params
,
2071 enum built_in_function builtin_id
)
2075 m_return_type (return_type
),
2078 m_is_variadic (is_variadic
),
2079 m_builtin_id (builtin_id
),
2083 for (int i
= 0; i
< num_params
; i
++)
2084 m_params
.safe_push (params
[i
]);
2087 /* Implementation of pure virtual hook recording::memento::replay_into
2088 for recording::function. */
2091 recording::function::replay_into (replayer
*r
)
2093 /* Convert m_params to a vec of playback param. */
2094 auto_vec
<playback::param
*> params
;
2096 recording::param
*param
;
2097 params
.create (m_params
.length ());
2098 FOR_EACH_VEC_ELT (m_params
, i
, param
)
2099 params
.safe_push (param
->playback_param ());
2101 set_playback_obj (r
->new_function (playback_location (r
, m_loc
),
2103 m_return_type
->playback_type (),
2110 /* Create a recording::local instance and add it to
2111 the functions's context's list of mementos, and to the function's
2114 Implements the post-error-checking part of
2115 gcc_jit_function_new_local. */
2118 recording::function::new_local (recording::location
*loc
,
2122 local
*result
= new local (this, loc
, type
, new_string (name
));
2123 m_ctxt
->record (result
);
2124 m_locals
.safe_push (result
);
2128 /* Create a recording::block instance and add it to
2129 the functions's context's list of mementos, and to the function's
2132 Implements the post-error-checking part of
2133 gcc_jit_function_new_block. */
2136 recording::function::new_block (const char *name
)
2138 gcc_assert (m_kind
!= GCC_JIT_FUNCTION_IMPORTED
);
2140 recording::block
*result
=
2141 new recording::block (this, m_blocks
.length (), new_string (name
));
2142 m_ctxt
->record (result
);
2143 m_blocks
.safe_push (result
);
2147 /* Override the default implementation of
2148 recording::memento::write_to_dump by dumping a C-like
2149 representation of the function; either like a prototype
2150 for GCC_JIT_FUNCTION_IMPORTED, or like a full definition for
2151 all other kinds of function. */
2154 recording::function::write_to_dump (dump
&d
)
2158 default: gcc_unreachable ();
2159 case GCC_JIT_FUNCTION_EXPORTED
:
2160 case GCC_JIT_FUNCTION_IMPORTED
:
2161 d
.write ("extern ");
2163 case GCC_JIT_FUNCTION_INTERNAL
:
2164 d
.write ("static ");
2166 case GCC_JIT_FUNCTION_ALWAYS_INLINE
:
2167 d
.write ("static inline ");
2170 d
.write ("%s\n", m_return_type
->get_debug_string ());
2172 if (d
.update_locations ())
2173 m_loc
= d
.make_location ();
2175 d
.write ("%s (", get_debug_string ());
2178 recording::param
*param
;
2179 FOR_EACH_VEC_ELT (m_params
, i
, param
)
2184 param
->get_type ()->get_debug_string (),
2185 param
->get_debug_string ());
2188 if (m_kind
== GCC_JIT_FUNCTION_IMPORTED
)
2190 d
.write ("; /* (imported) */\n\n");
2200 FOR_EACH_VEC_ELT (m_locals
, i
, var
)
2201 var
->write_to_dump (d
);
2202 if (m_locals
.length ())
2205 /* Write each block: */
2206 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
2210 b
->write_to_dump (d
);
2217 /* Pre-compilation validation of a function, for those things we can't
2218 check until the context is (supposedly) fully-populated. */
2221 recording::function::validate ()
2223 /* Complain about empty functions with non-void return type. */
2224 if (m_kind
!= GCC_JIT_FUNCTION_IMPORTED
2225 && m_return_type
!= m_ctxt
->get_type (GCC_JIT_TYPE_VOID
))
2226 if (0 == m_blocks
.length ())
2227 m_ctxt
->add_error (m_loc
,
2228 "function %s returns non-void (type: %s)"
2229 " but has no blocks",
2230 get_debug_string (),
2231 m_return_type
->get_debug_string ());
2233 /* Check that all blocks are terminated. */
2234 int num_invalid_blocks
= 0;
2239 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
2240 if (!b
->validate ())
2241 num_invalid_blocks
++;
2244 /* Check that all blocks are reachable. */
2245 if (m_blocks
.length () > 0 && 0 == num_invalid_blocks
)
2247 /* Iteratively walk the graph of blocks, marking their "m_is_reachable"
2248 flag, starting at the initial block. */
2249 auto_vec
<block
*> worklist (m_blocks
.length ());
2250 worklist
.safe_push (m_blocks
[0]);
2251 while (worklist
.length () > 0)
2253 block
*b
= worklist
.pop ();
2254 b
->m_is_reachable
= true;
2256 /* Add successor blocks that aren't yet marked to the worklist. */
2257 /* We checked that each block has a terminating statement above . */
2258 block
*next1
, *next2
;
2259 int n
= b
->get_successor_blocks (&next1
, &next2
);
2265 if (!next2
->m_is_reachable
)
2266 worklist
.safe_push (next2
);
2269 if (!next1
->m_is_reachable
)
2270 worklist
.safe_push (next1
);
2277 /* Now complain about any blocks that haven't been marked. */
2281 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
2282 if (!b
->m_is_reachable
)
2283 m_ctxt
->add_error (b
->get_loc (),
2284 "unreachable block: %s",
2285 b
->get_debug_string ());
2290 /* Implements the post-error-checking part of
2291 gcc_jit_function_dump_to_dot. */
2294 recording::function::dump_to_dot (const char *path
)
2296 FILE *fp
= fopen (path
, "w");
2300 pretty_printer the_pp
;
2301 the_pp
.buffer
->stream
= fp
;
2303 pretty_printer
*pp
= &the_pp
;
2306 "digraph %s {\n", get_debug_string ());
2312 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
2313 b
->dump_to_dot (pp
);
2320 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
2321 b
->dump_edges_to_dot (pp
);
2324 pp_printf (pp
, "}\n");
2329 /* Implementation of recording::memento::make_debug_string for
2333 recording::function::make_debug_string ()
2338 /* The implementation of class gcc::jit::recording::block. */
2340 /* Create a recording::eval instance and add it to
2341 the block's context's list of mementos, and to the block's
2344 Implements the post-error-checking part of
2345 gcc_jit_block_add_eval. */
2348 recording::block::add_eval (recording::location
*loc
,
2349 recording::rvalue
*rvalue
)
2351 statement
*result
= new eval (this, loc
, rvalue
);
2352 m_ctxt
->record (result
);
2353 m_statements
.safe_push (result
);
2356 /* Create a recording::assignment instance and add it to
2357 the block's context's list of mementos, and to the block's
2360 Implements the post-error-checking part of
2361 gcc_jit_block_add_assignment. */
2364 recording::block::add_assignment (recording::location
*loc
,
2365 recording::lvalue
*lvalue
,
2366 recording::rvalue
*rvalue
)
2368 statement
*result
= new assignment (this, loc
, lvalue
, rvalue
);
2369 m_ctxt
->record (result
);
2370 m_statements
.safe_push (result
);
2373 /* Create a recording::assignment_op instance and add it to
2374 the block's context's list of mementos, and to the block's
2377 Implements the post-error-checking part of
2378 gcc_jit_block_add_assignment_op. */
2381 recording::block::add_assignment_op (recording::location
*loc
,
2382 recording::lvalue
*lvalue
,
2383 enum gcc_jit_binary_op op
,
2384 recording::rvalue
*rvalue
)
2386 statement
*result
= new assignment_op (this, loc
, lvalue
, op
, rvalue
);
2387 m_ctxt
->record (result
);
2388 m_statements
.safe_push (result
);
2391 /* Create a recording::comment instance and add it to
2392 the block's context's list of mementos, and to the block's
2395 Implements the post-error-checking part of
2396 gcc_jit_block_add_comment. */
2399 recording::block::add_comment (recording::location
*loc
,
2402 statement
*result
= new comment (this, loc
, new_string (text
));
2403 m_ctxt
->record (result
);
2404 m_statements
.safe_push (result
);
2407 /* Create a recording::end_with_conditional instance and add it to
2408 the block's context's list of mementos, and to the block's
2411 Implements the post-error-checking part of
2412 gcc_jit_block_end_with_conditional. */
2415 recording::block::end_with_conditional (recording::location
*loc
,
2416 recording::rvalue
*boolval
,
2417 recording::block
*on_true
,
2418 recording::block
*on_false
)
2420 statement
*result
= new conditional (this, loc
, boolval
, on_true
, on_false
);
2421 m_ctxt
->record (result
);
2422 m_statements
.safe_push (result
);
2423 m_has_been_terminated
= true;
2426 /* Create a recording::end_with_jump instance and add it to
2427 the block's context's list of mementos, and to the block's
2430 Implements the post-error-checking part of
2431 gcc_jit_block_end_with_jump. */
2434 recording::block::end_with_jump (recording::location
*loc
,
2435 recording::block
*target
)
2437 statement
*result
= new jump (this, loc
, target
);
2438 m_ctxt
->record (result
);
2439 m_statements
.safe_push (result
);
2440 m_has_been_terminated
= true;
2443 /* Create a recording::end_with_return instance and add it to
2444 the block's context's list of mementos, and to the block's
2447 Implements the post-error-checking parts of
2448 gcc_jit_block_end_with_return and
2449 gcc_jit_block_end_with_void_return. */
2452 recording::block::end_with_return (recording::location
*loc
,
2453 recording::rvalue
*rvalue
)
2455 /* This is used by both gcc_jit_function_add_return and
2456 gcc_jit_function_add_void_return; rvalue will be non-NULL for
2457 the former and NULL for the latter. */
2458 statement
*result
= new return_ (this, loc
, rvalue
);
2459 m_ctxt
->record (result
);
2460 m_statements
.safe_push (result
);
2461 m_has_been_terminated
= true;
2464 /* Override the default implementation of
2465 recording::memento::write_to_dump for blocks by writing
2466 an unindented block name as a label, followed by the indented
2476 recording::block::write_to_dump (dump
&d
)
2478 d
.write ("%s:\n", get_debug_string ());
2482 FOR_EACH_VEC_ELT (m_statements
, i
, s
)
2483 s
->write_to_dump (d
);
2486 /* Validate a block by ensuring that it has been terminated. */
2489 recording::block::validate ()
2491 if (!has_been_terminated ())
2493 statement
*stmt
= get_last_statement ();
2494 location
*loc
= stmt
? stmt
->get_loc () : NULL
;
2495 m_func
->get_context ()->add_error (loc
,
2496 "unterminated block in %s: %s",
2497 m_func
->get_debug_string (),
2498 get_debug_string ());
2505 /* Get the source-location of a block by using that of the first
2506 statement within it, if any. */
2508 recording::location
*
2509 recording::block::get_loc () const
2511 recording::statement
*stmt
= get_first_statement ();
2513 return stmt
->get_loc ();
2518 /* Get the first statement within a block, if any. */
2520 recording::statement
*
2521 recording::block::get_first_statement () const
2523 if (m_statements
.length ())
2524 return m_statements
[0];
2529 /* Get the last statement within a block, if any. */
2531 recording::statement
*
2532 recording::block::get_last_statement () const
2534 if (m_statements
.length ())
2535 return m_statements
[m_statements
.length () - 1];
2540 /* Assuming that this block has been terminated, get the number of
2541 successor blocks, which will be 0, 1 or 2, for return, unconditional
2542 jump, and conditional jump respectively.
2543 NEXT1 and NEXT2 must be non-NULL. The first successor block (if any)
2544 is written to NEXT1, and the second (if any) to NEXT2.
2546 Used when validating functions, and when dumping dot representations
2550 recording::block::get_successor_blocks (block
**next1
, block
**next2
) const
2552 gcc_assert (m_has_been_terminated
);
2555 statement
*last_statement
= get_last_statement ();
2556 gcc_assert (last_statement
);
2557 return last_statement
->get_successor_blocks (next1
, next2
);
2560 /* Implementation of pure virtual hook recording::memento::replay_into
2561 for recording::block. */
2564 recording::block::replay_into (replayer
*)
2566 set_playback_obj (m_func
->playback_function ()
2567 ->new_block (playback_string (m_name
)));
2570 /* Implementation of recording::memento::make_debug_string for
2574 recording::block::make_debug_string ()
2579 return string::from_printf (m_ctxt
,
2580 "<UNNAMED BLOCK %p>",
2584 /* Dump a block in graphviz form into PP, capturing the block name (if
2585 any) and the statements. */
2588 recording::block::dump_to_dot (pretty_printer
*pp
)
2592 "[shape=record,style=filled,fillcolor=white,label=\"{"),
2594 pp_write_text_to_stream (pp
);
2597 pp_string (pp
, m_name
->c_str ());
2598 pp_string (pp
, ":");
2600 pp_write_text_as_dot_label_to_stream (pp
, true /*for_record*/);
2605 FOR_EACH_VEC_ELT (m_statements
, i
, s
)
2607 pp_string (pp
, s
->get_debug_string ());
2609 pp_write_text_as_dot_label_to_stream (pp
, true /*for_record*/);
2617 /* Dump the out-edges of the block in graphviz form into PP. */
2620 recording::block::dump_edges_to_dot (pretty_printer
*pp
)
2623 int num_succs
= get_successor_blocks (&next
[0], &next
[1]);
2624 for (int i
= 0; i
< num_succs
; i
++)
2626 "\tblock_%d:s -> block_%d:n;\n",
2627 m_index
, next
[i
]->m_index
);
2630 /* The implementation of class gcc::jit::recording::global. */
2632 /* Implementation of pure virtual hook recording::memento::replay_into
2633 for recording::global. */
2636 recording::global::replay_into (replayer
*r
)
2638 set_playback_obj (r
->new_global (playback_location (r
, m_loc
),
2639 m_type
->playback_type (),
2640 playback_string (m_name
)));
2643 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_int. */
2645 /* Implementation of pure virtual hook recording::memento::replay_into
2646 for recording::memento_of_new_rvalue_from_int. */
2649 recording::memento_of_new_rvalue_from_int::replay_into (replayer
*r
)
2651 set_playback_obj (r
->new_rvalue_from_int (m_type
->playback_type (),
2655 /* Implementation of recording::memento::make_debug_string for
2656 rvalue_from_int, rendering it as
2662 recording::memento_of_new_rvalue_from_int::make_debug_string ()
2664 return string::from_printf (m_ctxt
,
2666 m_type
->get_debug_string (),
2670 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_double. */
2672 /* Implementation of pure virtual hook recording::memento::replay_into
2673 for recording::memento_of_new_rvalue_from_double. */
2676 recording::memento_of_new_rvalue_from_double::replay_into (replayer
*r
)
2678 set_playback_obj (r
->new_rvalue_from_double (m_type
->playback_type (),
2682 /* Implementation of recording::memento::make_debug_string for
2683 rvalue_from_double, rendering it as
2689 recording::memento_of_new_rvalue_from_double::make_debug_string ()
2691 return string::from_printf (m_ctxt
,
2693 m_type
->get_debug_string (),
2697 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_ptr. */
2699 /* Implementation of pure virtual hook recording::memento::replay_into
2700 for recording::memento_of_new_rvalue_from_ptr. */
2703 recording::memento_of_new_rvalue_from_ptr::replay_into (replayer
*r
)
2705 set_playback_obj (r
->new_rvalue_from_ptr (m_type
->playback_type (),
2709 /* Implementation of recording::memento::make_debug_string for
2710 rvalue_from_ptr, rendering it as
2715 Zero is rendered as NULL e.g.
2719 recording::memento_of_new_rvalue_from_ptr::make_debug_string ()
2721 if (m_value
!= NULL
)
2722 return string::from_printf (m_ctxt
,
2724 m_type
->get_debug_string (), m_value
);
2726 return string::from_printf (m_ctxt
,
2728 m_type
->get_debug_string ());
2731 /* The implementation of class gcc::jit::recording::memento_of_new_string_literal. */
2733 /* Implementation of pure virtual hook recording::memento::replay_into
2734 for recording::memento_of_new_string_literal. */
2737 recording::memento_of_new_string_literal::replay_into (replayer
*r
)
2739 set_playback_obj (r
->new_string_literal (m_value
->c_str ()));
2742 /* Implementation of recording::memento::make_debug_string for
2746 recording::memento_of_new_string_literal::make_debug_string ()
2748 return string::from_printf (m_ctxt
,
2749 m_value
->get_debug_string ());
2752 /* The implementation of class gcc::jit::recording::unary_op. */
2754 /* Implementation of pure virtual hook recording::memento::replay_into
2755 for recording::unary_op. */
2758 recording::unary_op::replay_into (replayer
*r
)
2760 set_playback_obj (r
->new_unary_op (playback_location (r
, m_loc
),
2762 get_type ()->playback_type (),
2763 m_a
->playback_rvalue ()));
2766 /* Implementation of recording::memento::make_debug_string for
2769 static const char * const unary_op_strings
[] = {
2770 "-", /* GCC_JIT_UNARY_OP_MINUS */
2771 "~", /* GCC_JIT_UNARY_OP_BITWISE_NEGATE */
2772 "!", /* GCC_JIT_UNARY_OP_LOGICAL_NEGATE */
2776 recording::unary_op::make_debug_string ()
2778 return string::from_printf (m_ctxt
,
2780 unary_op_strings
[m_op
],
2781 m_a
->get_debug_string ());
2784 /* The implementation of class gcc::jit::recording::binary_op. */
2786 /* Implementation of pure virtual hook recording::memento::replay_into
2787 for recording::binary_op. */
2790 recording::binary_op::replay_into (replayer
*r
)
2792 set_playback_obj (r
->new_binary_op (playback_location (r
, m_loc
),
2794 get_type ()->playback_type (),
2795 m_a
->playback_rvalue (),
2796 m_b
->playback_rvalue ()));
2799 /* Implementation of recording::memento::make_debug_string for
2802 static const char * const binary_op_strings
[] = {
2803 "+", /* GCC_JIT_BINARY_OP_PLUS */
2804 "-", /* GCC_JIT_BINARY_OP_MINUS */
2805 "*", /* GCC_JIT_BINARY_OP_MULT */
2806 "/", /* GCC_JIT_BINARY_OP_DIVIDE */
2807 "%", /* GCC_JIT_BINARY_OP_MODULO */
2808 "&", /* GCC_JIT_BINARY_OP_BITWISE_AND */
2809 "^", /* GCC_JIT_BINARY_OP_BITWISE_XOR */
2810 "|", /* GCC_JIT_BINARY_OP_BITWISE_OR */
2811 "&&", /* GCC_JIT_BINARY_OP_LOGICAL_AND */
2812 "||", /* GCC_JIT_BINARY_OP_LOGICAL_OR */
2813 "<<", /* GCC_JIT_BINARY_OP_LSHIFT */
2814 ">>", /* GCC_JIT_BINARY_OP_RSHIFT */
2818 recording::binary_op::make_debug_string ()
2820 return string::from_printf (m_ctxt
,
2822 m_a
->get_debug_string (),
2823 binary_op_strings
[m_op
],
2824 m_b
->get_debug_string ());
2827 /* The implementation of class gcc::jit::recording::comparison. */
2829 /* Implementation of recording::memento::make_debug_string for
2832 static const char * const comparison_strings
[] =
2834 "==", /* GCC_JIT_COMPARISON_EQ */
2835 "!=", /* GCC_JIT_COMPARISON_NE */
2836 "<", /* GCC_JIT_COMPARISON_LT */
2837 "<=", /* GCC_JIT_COMPARISON_LE */
2838 ">", /* GCC_JIT_COMPARISON_GT */
2839 ">=", /* GCC_JIT_COMPARISON_GE */
2843 recording::comparison::make_debug_string ()
2845 return string::from_printf (m_ctxt
,
2847 m_a
->get_debug_string (),
2848 comparison_strings
[m_op
],
2849 m_b
->get_debug_string ());
2852 /* Implementation of pure virtual hook recording::memento::replay_into
2853 for recording::comparison. */
2856 recording::comparison::replay_into (replayer
*r
)
2858 set_playback_obj (r
->new_comparison (playback_location (r
, m_loc
),
2860 m_a
->playback_rvalue (),
2861 m_b
->playback_rvalue ()));
2864 /* Implementation of pure virtual hook recording::memento::replay_into
2865 for recording::cast. */
2868 recording::cast::replay_into (replayer
*r
)
2870 set_playback_obj (r
->new_cast (playback_location (r
, m_loc
),
2871 m_rvalue
->playback_rvalue (),
2872 get_type ()->playback_type ()));
2875 /* Implementation of recording::memento::make_debug_string for
2879 recording::cast::make_debug_string ()
2881 return string::from_printf (m_ctxt
,
2883 get_type ()->get_debug_string (),
2884 m_rvalue
->get_debug_string ());
2887 /* The implementation of class gcc::jit::recording::call. */
2889 /* The constructor for gcc::jit::recording::call. */
2891 recording::call::call (recording::context
*ctxt
,
2892 recording::location
*loc
,
2893 recording::function
*func
,
2896 : rvalue (ctxt
, loc
, func
->get_return_type ()),
2900 for (int i
= 0; i
< numargs
; i
++)
2901 m_args
.safe_push (args
[i
]);
2904 /* Implementation of pure virtual hook recording::memento::replay_into
2905 for recording::call. */
2908 recording::call::replay_into (replayer
*r
)
2910 auto_vec
<playback::rvalue
*> playback_args
;
2911 playback_args
.create (m_args
.length ());
2912 for (unsigned i
= 0; i
< m_args
.length (); i
++)
2913 playback_args
.safe_push (m_args
[i
]->playback_rvalue ());
2915 set_playback_obj (r
->new_call (playback_location (r
, m_loc
),
2916 m_func
->playback_function (),
2920 /* Implementation of recording::memento::make_debug_string for
2924 recording::call::make_debug_string ()
2926 /* First, build a buffer for the arguments. */
2927 /* Calculate length of said buffer. */
2928 size_t sz
= 1; /* nil terminator */
2929 for (unsigned i
= 0; i
< m_args
.length (); i
++)
2931 sz
+= strlen (m_args
[i
]->get_debug_string ());
2932 sz
+= 2; /* ", " separator */
2935 /* Now allocate and populate the buffer. */
2936 char *argbuf
= new char[sz
];
2939 for (unsigned i
= 0; i
< m_args
.length (); i
++)
2941 strcpy (argbuf
+ len
, m_args
[i
]->get_debug_string ());
2942 len
+= strlen (m_args
[i
]->get_debug_string ());
2943 if (i
+ 1 < m_args
.length ())
2945 strcpy (argbuf
+ len
, ", ");
2951 /* ...and use it to get the string for the call as a whole. */
2952 string
*result
= string::from_printf (m_ctxt
,
2954 m_func
->get_debug_string (),
2962 /* The implementation of class gcc::jit::recording::call_through_ptr. */
2964 /* The constructor for recording::call_through_ptr. */
2966 recording::call_through_ptr::call_through_ptr (recording::context
*ctxt
,
2967 recording::location
*loc
,
2968 recording::rvalue
*fn_ptr
,
2971 : rvalue (ctxt
, loc
,
2972 fn_ptr
->get_type ()->dereference ()
2973 ->as_a_function_type ()->get_return_type ()),
2977 for (int i
= 0; i
< numargs
; i
++)
2978 m_args
.safe_push (args
[i
]);
2981 /* Implementation of pure virtual hook recording::memento::replay_into
2982 for recording::call_through_ptr. */
2985 recording::call_through_ptr::replay_into (replayer
*r
)
2987 auto_vec
<playback::rvalue
*> playback_args
;
2988 playback_args
.create (m_args
.length ());
2989 for (unsigned i
= 0; i
< m_args
.length (); i
++)
2990 playback_args
.safe_push (m_args
[i
]->playback_rvalue ());
2992 set_playback_obj (r
->new_call_through_ptr (playback_location (r
, m_loc
),
2993 m_fn_ptr
->playback_rvalue (),
2997 /* Implementation of recording::memento::make_debug_string for
2998 calls through function ptrs. */
3001 recording::call_through_ptr::make_debug_string ()
3003 /* First, build a buffer for the arguments. */
3004 /* Calculate length of said buffer. */
3005 size_t sz
= 1; /* nil terminator */
3006 for (unsigned i
= 0; i
< m_args
.length (); i
++)
3008 sz
+= strlen (m_args
[i
]->get_debug_string ());
3009 sz
+= 2; /* ", " separator */
3012 /* Now allocate and populate the buffer. */
3013 char *argbuf
= new char[sz
];
3016 for (unsigned i
= 0; i
< m_args
.length (); i
++)
3018 strcpy (argbuf
+ len
, m_args
[i
]->get_debug_string ());
3019 len
+= strlen (m_args
[i
]->get_debug_string ());
3020 if (i
+ 1 < m_args
.length ())
3022 strcpy (argbuf
+ len
, ", ");
3028 /* ...and use it to get the string for the call as a whole. */
3029 string
*result
= string::from_printf (m_ctxt
,
3031 m_fn_ptr
->get_debug_string (),
3039 /* The implementation of class gcc::jit::recording::array_access. */
3041 /* Implementation of pure virtual hook recording::memento::replay_into
3042 for recording::array_access. */
3045 recording::array_access::replay_into (replayer
*r
)
3048 r
->new_array_access (playback_location (r
, m_loc
),
3049 m_ptr
->playback_rvalue (),
3050 m_index
->playback_rvalue ()));
3053 /* Implementation of recording::memento::make_debug_string for
3057 recording::array_access::make_debug_string ()
3059 return string::from_printf (m_ctxt
,
3061 m_ptr
->get_debug_string (),
3062 m_index
->get_debug_string ());
3065 /* The implementation of class gcc::jit::recording::access_field_of_lvalue. */
3067 /* Implementation of pure virtual hook recording::memento::replay_into
3068 for recording::access_field_of_lvalue. */
3071 recording::access_field_of_lvalue::replay_into (replayer
*r
)
3074 m_lvalue
->playback_lvalue ()
3075 ->access_field (playback_location (r
, m_loc
),
3076 m_field
->playback_field ()));
3080 /* Implementation of recording::memento::make_debug_string for
3081 accessing a field of an lvalue. */
3084 recording::access_field_of_lvalue::make_debug_string ()
3086 return string::from_printf (m_ctxt
,
3088 m_lvalue
->get_debug_string (),
3089 m_field
->get_debug_string ());
3092 /* The implementation of class gcc::jit::recording::access_field_rvalue. */
3094 /* Implementation of pure virtual hook recording::memento::replay_into
3095 for recording::access_field_rvalue. */
3098 recording::access_field_rvalue::replay_into (replayer
*r
)
3101 m_rvalue
->playback_rvalue ()
3102 ->access_field (playback_location (r
, m_loc
),
3103 m_field
->playback_field ()));
3106 /* Implementation of recording::memento::make_debug_string for
3107 accessing a field of an rvalue. */
3110 recording::access_field_rvalue::make_debug_string ()
3112 return string::from_printf (m_ctxt
,
3114 m_rvalue
->get_debug_string (),
3115 m_field
->get_debug_string ());
3118 /* The implementation of class
3119 gcc::jit::recording::dereference_field_rvalue. */
3121 /* Implementation of pure virtual hook recording::memento::replay_into
3122 for recording::dereference_field_rvalue. */
3125 recording::dereference_field_rvalue::replay_into (replayer
*r
)
3128 m_rvalue
->playback_rvalue ()->
3129 dereference_field (playback_location (r
, m_loc
),
3130 m_field
->playback_field ()));
3133 /* Implementation of recording::memento::make_debug_string for
3134 dereferencing a field of an rvalue. */
3137 recording::dereference_field_rvalue::make_debug_string ()
3139 return string::from_printf (m_ctxt
,
3141 m_rvalue
->get_debug_string (),
3142 m_field
->get_debug_string ());
3145 /* The implementation of class gcc::jit::recording::dereference_rvalue. */
3147 /* Implementation of pure virtual hook recording::memento::replay_into
3148 for recording::dereference_rvalue. */
3151 recording::dereference_rvalue::replay_into (replayer
*r
)
3154 m_rvalue
->playback_rvalue ()->
3155 dereference (playback_location (r
, m_loc
)));
3158 /* Implementation of recording::memento::make_debug_string for
3159 dereferencing an rvalue. */
3162 recording::dereference_rvalue::make_debug_string ()
3164 return string::from_printf (m_ctxt
,
3166 m_rvalue
->get_debug_string ());
3169 /* The implementation of class gcc::jit::recording::get_address_of_lvalue. */
3171 /* Implementation of pure virtual hook recording::memento::replay_into
3172 for recording::get_address_of_lvalue. */
3175 recording::get_address_of_lvalue::replay_into (replayer
*r
)
3178 m_lvalue
->playback_lvalue ()->
3179 get_address (playback_location (r
, m_loc
)));
3182 /* Implementation of recording::memento::make_debug_string for
3183 getting the address of an lvalue. */
3186 recording::get_address_of_lvalue::make_debug_string ()
3188 return string::from_printf (m_ctxt
,
3190 m_lvalue
->get_debug_string ());
3193 /* The implementation of class gcc::jit::recording::local. */
3195 /* Implementation of pure virtual hook recording::memento::replay_into
3196 for recording::local. */
3199 recording::local::replay_into (replayer
*r
)
3202 m_func
->playback_function ()
3203 ->new_local (playback_location (r
, m_loc
),
3204 m_type
->playback_type (),
3205 playback_string (m_name
)));
3208 /* Override the default implementation of
3209 recording::memento::write_to_dump for locals by writing
3211 for use at the top of the function body as if it were a
3215 recording::local::write_to_dump (dump
&d
)
3217 if (d
.update_locations ())
3218 m_loc
= d
.make_location ();
3219 d
.write(" %s %s;\n",
3220 m_type
->get_debug_string (),
3221 get_debug_string ());
3224 /* The implementation of class gcc::jit::recording::statement. */
3226 /* We poison the default implementation of
3227 gcc::jit::recording::statement::get_successor_blocks
3228 since this vfunc must only ever be called on terminator
3232 recording::statement::get_successor_blocks (block
**/
*out_next1*/
,
3233 block
**/
*out_next2*/
) const
3235 /* The base class implementation is for non-terminating statements,
3236 and thus should never be called. */
3241 /* Extend the default implementation of
3242 recording::memento::write_to_dump for statements by (if requested)
3243 updating the location of the statement to the current location in
3247 recording::statement::write_to_dump (dump
&d
)
3249 memento::write_to_dump (d
);
3250 if (d
.update_locations ())
3251 m_loc
= d
.make_location ();
3254 /* The implementation of class gcc::jit::recording::eval. */
3256 /* Implementation of pure virtual hook recording::memento::replay_into
3257 for recording::eval. */
3260 recording::eval::replay_into (replayer
*r
)
3262 playback_block (get_block ())
3263 ->add_eval (playback_location (r
),
3264 m_rvalue
->playback_rvalue ());
3267 /* Implementation of recording::memento::make_debug_string for
3268 an eval statement. */
3271 recording::eval::make_debug_string ()
3273 return string::from_printf (m_ctxt
,
3275 m_rvalue
->get_debug_string ());
3278 /* The implementation of class gcc::jit::recording::assignment. */
3280 /* Implementation of pure virtual hook recording::memento::replay_into
3281 for recording::assignment. */
3284 recording::assignment::replay_into (replayer
*r
)
3286 playback_block (get_block ())
3287 ->add_assignment (playback_location (r
),
3288 m_lvalue
->playback_lvalue (),
3289 m_rvalue
->playback_rvalue ());
3292 /* Implementation of recording::memento::make_debug_string for
3293 an assignment statement. */
3296 recording::assignment::make_debug_string ()
3298 return string::from_printf (m_ctxt
,
3300 m_lvalue
->get_debug_string (),
3301 m_rvalue
->get_debug_string ());
3304 /* The implementation of class gcc::jit::recording::assignment_op. */
3306 /* Implementation of pure virtual hook recording::memento::replay_into
3307 for recording::assignment_op. */
3310 recording::assignment_op::replay_into (replayer
*r
)
3312 playback::type
*result_type
=
3313 m_lvalue
->playback_lvalue ()->get_type ();
3315 playback::rvalue
*binary_op
=
3316 r
->new_binary_op (playback_location (r
),
3319 m_lvalue
->playback_rvalue (),
3320 m_rvalue
->playback_rvalue ());
3322 playback_block (get_block ())
3323 ->add_assignment (playback_location (r
),
3324 m_lvalue
->playback_lvalue (),
3328 /* Implementation of recording::memento::make_debug_string for
3329 an assignment_op statement. */
3332 recording::assignment_op::make_debug_string ()
3334 return string::from_printf (m_ctxt
,
3336 m_lvalue
->get_debug_string (),
3337 binary_op_strings
[m_op
],
3338 m_rvalue
->get_debug_string ());
3341 /* The implementation of class gcc::jit::recording::comment. */
3343 /* Implementation of pure virtual hook recording::memento::replay_into
3344 for recording::comment. */
3347 recording::comment::replay_into (replayer
*r
)
3349 playback_block (get_block ())
3350 ->add_comment (playback_location (r
),
3354 /* Implementation of recording::memento::make_debug_string for
3355 a comment "statement". */
3358 recording::comment::make_debug_string ()
3360 return string::from_printf (m_ctxt
,
3365 /* The implementation of class gcc::jit::recording::conditional. */
3367 /* Implementation of pure virtual hook recording::memento::replay_into
3368 for recording::conditional. */
3371 recording::conditional::replay_into (replayer
*r
)
3373 playback_block (get_block ())
3374 ->add_conditional (playback_location (r
),
3375 m_boolval
->playback_rvalue (),
3376 playback_block (m_on_true
),
3377 playback_block (m_on_false
));
3380 /* Override the poisoned default implementation of
3381 gcc::jit::recording::statement::get_successor_blocks
3383 A conditional jump has 2 successor blocks. */
3386 recording::conditional::get_successor_blocks (block
**out_next1
,
3387 block
**out_next2
) const
3389 *out_next1
= m_on_true
;
3390 *out_next2
= m_on_false
;
3394 /* Implementation of recording::memento::make_debug_string for
3395 a conditional jump statement. */
3398 recording::conditional::make_debug_string ()
3401 return string::from_printf (m_ctxt
,
3402 "if (%s) goto %s; else goto %s;",
3403 m_boolval
->get_debug_string (),
3404 m_on_true
->get_debug_string (),
3405 m_on_false
->get_debug_string ());
3407 return string::from_printf (m_ctxt
,
3409 m_boolval
->get_debug_string (),
3410 m_on_true
->get_debug_string ());
3413 /* The implementation of class gcc::jit::recording::jump. */
3415 /* Implementation of pure virtual hook recording::memento::replay_into
3416 for recording::jump. */
3419 recording::jump::replay_into (replayer
*r
)
3421 playback_block (get_block ())
3422 ->add_jump (playback_location (r
),
3423 m_target
->playback_block ());
3426 /* Override the poisoned default implementation of
3427 gcc::jit::recording::statement::get_successor_blocks
3429 An unconditional jump has 1 successor block. */
3432 recording::jump::get_successor_blocks (block
**out_next1
,
3433 block
**/
*out_next2*/
) const
3435 *out_next1
= m_target
;
3439 /* Implementation of recording::memento::make_debug_string for
3440 a unconditional jump statement. */
3443 recording::jump::make_debug_string ()
3445 return string::from_printf (m_ctxt
,
3447 m_target
->get_debug_string ());
3450 /* The implementation of class gcc::jit::recording::return_. */
3452 /* Implementation of pure virtual hook recording::memento::replay_into
3453 for recording::return_. */
3456 recording::return_::replay_into (replayer
*r
)
3458 playback_block (get_block ())
3459 ->add_return (playback_location (r
),
3460 m_rvalue
? m_rvalue
->playback_rvalue () : NULL
);
3463 /* Override the poisoned default implementation of
3464 gcc::jit::recording::statement::get_successor_blocks
3466 A return statement has no successor block. */
3469 recording::return_::get_successor_blocks (block
**/
*out_next1*/
,
3470 block
**/
*out_next2*/
) const
3475 /* Implementation of recording::memento::make_debug_string for
3476 a return statement (covers both those with and without rvalues). */
3479 recording::return_::make_debug_string ()
3482 return string::from_printf (m_ctxt
,
3484 m_rvalue
->get_debug_string ());
3486 return string::from_printf (m_ctxt
,
3490 } // namespace gcc::jit