1 /* Internals of libgccjit: classes for recording calls made to the JIT API.
2 Copyright (C) 2013-2015 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
25 #include "pretty-print.h"
31 #include "jit-common.h"
32 #include "jit-builtins.h"
33 #include "jit-logging.h"
34 #include "jit-recording.h"
35 #include "jit-playback.h"
42 dump::dump (recording::context
&ctxt
,
44 bool update_locations
)
46 m_filename (filename
),
47 m_update_locations (update_locations
),
51 m_file
= fopen (filename
, "w");
54 "error opening dump file %s for writing: %s",
63 int err
= fclose (m_file
);
65 m_ctxt
.add_error (NULL
,
66 "error closing dump file %s: %s",
72 /* Write the given message to the dump, using printf-formatting
73 conventions, updating the line/column within the dump.
75 Emit an error on the context if a failure occurs. */
78 dump::write (const char *fmt
, ...)
83 /* If there was an error opening the file, we've already reported it.
84 Don't attempt further work. */
89 vasprintf (&buf
, fmt
, ap
);
94 m_ctxt
.add_error (NULL
, "malloc failure writing to dumpfile %s",
99 if (fwrite (buf
, strlen (buf
), 1, m_file
) != 1)
100 m_ctxt
.add_error (NULL
, "error writing to dump file %s",
103 /* Flush after each line, to ease debugging crashes. */
106 /* Update line/column: */
107 for (const char *ptr
= buf
; *ptr
; ptr
++)
121 /* Construct a gcc::jit::recording::location instance for the current
122 location within the dump. */
124 recording::location
*
125 dump::make_location () const
127 return m_ctxt
.new_location (m_filename
, m_line
, m_column
,
128 /* We need to flag such locations as *not*
129 created by the user, so that
130 reproducer::get_identifier can cope with
131 them appearing *after* the memento that
136 /* A collection of allocations, all of which can be released together, to
137 avoid needing to track and release them individually. */
145 xstrdup_printf (const char *, ...)
146 ATTRIBUTE_RETURNS_NONNULL
150 xstrdup_printf_va (const char *, va_list ap
)
151 ATTRIBUTE_RETURNS_NONNULL
155 auto_vec
<void *> m_buffers
;
158 /* allocator's destructor. Call "free" on all of the allocations. */
160 allocator::~allocator ()
164 FOR_EACH_VEC_ELT (m_buffers
, i
, buffer
)
168 /* Formatted printing, allocating to a buffer (or exiting the process if
169 the allocation fails).
171 The buffer exists until the allocator is cleaned up, and is freed at
172 that point, so the caller doesn't need to track the result. */
175 allocator::xstrdup_printf (const char *fmt
, ...)
180 result
= xstrdup_printf_va (fmt
, ap
);
185 /* Formatted printing, allocating to a buffer (or exiting the process if
186 the allocation fails).
188 The buffer exists until the allocator is cleaned up, and is freed at
189 that point, so the caller doesn't need to track the result. */
192 allocator::xstrdup_printf_va (const char *fmt
, va_list ap
)
194 char *result
= xvasprintf (fmt
, ap
);
195 m_buffers
.safe_push (result
);
199 /* gcc::jit::reproducer is a subclass of gcc::jit::dump, used for
200 implementing gcc_jit_context_dump_reproducer_to_file. */
202 class reproducer
: public dump
205 reproducer (recording::context
&ctxt
,
206 const char *filename
);
209 write_params (const vec
<recording::context
*> &contexts
);
212 write_args (const vec
<recording::context
*> &contexts
);
215 make_identifier (recording::memento
*m
, const char *prefix
);
218 make_tmp_identifier (const char *prefix
, recording::memento
*m
);
221 get_identifier (recording::context
*ctxt
);
224 get_identifier (recording::memento
*m
);
227 get_identifier_as_rvalue (recording::rvalue
*m
);
230 get_identifier_as_lvalue (recording::lvalue
*m
);
233 get_identifier_as_type (recording::type
*m
);
236 xstrdup_printf (const char *, ...)
237 ATTRIBUTE_RETURNS_NONNULL
241 hash_map
<recording::memento
*, const char *> m_identifiers
;
242 allocator m_allocator
;
245 /* gcc::jit::reproducer's constructor. */
247 reproducer::reproducer (recording::context
&ctxt
,
248 const char *filename
) :
249 dump (ctxt
, filename
, 0),
255 /* Write out a list of contexts as a set of parameters within a
256 C function declaration. */
259 reproducer::write_params (const vec
<recording::context
*> &contexts
)
262 recording::context
*ctxt
;
263 FOR_EACH_VEC_ELT (contexts
, i
, ctxt
)
265 write ("gcc_jit_context *%s",
266 get_identifier (ctxt
));
267 if (i
< contexts
.length () - 1)
273 /* Write out a list of contexts as a set of arguments within a call
277 reproducer::write_args (const vec
<recording::context
*> &contexts
)
280 recording::context
*ctxt
;
281 FOR_EACH_VEC_ELT (contexts
, i
, ctxt
)
284 get_identifier (ctxt
));
285 if (i
< contexts
.length () - 1)
291 /* Generate a C identifier for the given memento, associating the generated
292 buffer with the memento (for future calls to get_identifier et al).
294 The reproducer will eventually clean up the buffer in its dtor. */
296 reproducer::make_identifier (recording::memento
*m
, const char *prefix
)
299 if (strlen (m
->get_debug_string ()) < 100)
301 result
= m_allocator
.xstrdup_printf ("%s_%s_%p",
303 m
->get_debug_string (),
305 for (char *p
= result
; *p
; p
++)
310 result
= m_allocator
.xstrdup_printf ("%s_%p",
312 m_identifiers
.put (m
, result
);
316 /* Generate a C identifier for a temporary variable.
317 The reproducer will eventually clean up the buffer in its dtor. */
320 reproducer::make_tmp_identifier (const char *prefix
, recording::memento
*m
)
322 return m_allocator
.xstrdup_printf ("%s_%s",
323 prefix
, get_identifier (m
));
326 /* Generate a C identifier for the given context.
327 The reproducer will eventually clean up the buffer in its dtor. */
330 reproducer::get_identifier (recording::context
*ctxt
)
332 return m_allocator
.xstrdup_printf ("ctxt_%p",
336 /* Locate the C identifier for the given memento, which is assumed to
337 have already been created via make_identifier. */
340 reproducer::get_identifier (recording::memento
*m
)
345 /* gcc_jit_context_dump_to_file (, , 1) generates and writes locations,
346 and hence these locations appear in the context's memento list
347 out-of-order: they appear in the context's memento list *after*
348 the memento that refers to them. For this case, it's simplest to
349 pretend that they're NULL when writing out the code to recreate the
350 memento that uses them. */
351 if (recording::location
*loc
= m
->dyn_cast_location ())
352 if (!loc
->created_by_user ())
355 const char **slot
= m_identifiers
.get (m
);
358 get_context ().add_error (NULL
,
359 "unable to find identifier for %p: %s",
361 m
->get_debug_string ());
367 /* Locate the C identifier for the given rvalue, wrapping it within
368 a gcc_*_as_rvalue upcast if necessary. */
371 reproducer::get_identifier_as_rvalue (recording::rvalue
*m
)
373 return m
->access_as_rvalue (*this);
376 /* Locate the C identifier for the given lvalue, wrapping it within
377 a gcc_*_as_lvalue upcast if necessary. */
380 reproducer::get_identifier_as_lvalue (recording::lvalue
*m
)
382 return m
->access_as_lvalue (*this);
385 /* Locate the C identifier for the given type, wrapping it within
386 a gcc_*_as_type upcast if necessary. */
389 reproducer::get_identifier_as_type (recording::type
*m
)
391 return m
->access_as_type (*this);
394 /* Formatted printing, allocating to a buffer (or exiting the process if
395 the allocation fails).
397 The buffer exists until the allocator is cleaned up, and is freed at
398 that point, so the caller doesn't need to track the result.
400 Note that we can't use ggc_printf since we're not within the compiler
401 proper (when within gcc_jit_context_dump_reproducer_to_file). */
404 reproducer::xstrdup_printf (const char *fmt
, ...)
409 result
= m_allocator
.xstrdup_printf_va (fmt
, ap
);
414 /**********************************************************************
416 **********************************************************************/
418 /* Get the playback::location for the given recording::location,
419 handling a NULL input with a NULL output. */
422 recording::playback_location (replayer
*r
, recording::location
*loc
)
425 return loc
->playback_location (r
);
430 /* Get a const char * for the given recording::string
431 handling a NULL input with a NULL output. */
434 recording::playback_string (recording::string
*str
)
437 return str
->c_str ();
442 /* Get the playback::block for the given recording::block,
443 handling a NULL input with a NULL output. */
446 recording::playback_block (recording::block
*b
)
449 return b
->playback_block ();
454 /* Methods of cc::jit::recording::context. */
456 /* The constructor for gcc::jit::recording::context, used by
457 gcc_jit_context_acquire and gcc_jit_context_new_child_context. */
459 recording::context::context (context
*parent_ctxt
)
461 m_parent_ctxt (parent_ctxt
),
462 m_toplevel_ctxt (m_parent_ctxt
? m_parent_ctxt
->m_toplevel_ctxt
: this),
464 m_first_error_str (NULL
),
465 m_owns_first_error_str (false),
466 m_last_error_str (NULL
),
467 m_owns_last_error_str (false),
473 m_builtins_manager(NULL
)
477 /* Inherit options from parent. */
479 i
< sizeof (m_str_options
) / sizeof (m_str_options
[0]);
482 const char *parent_opt
= parent_ctxt
->m_str_options
[i
];
483 m_str_options
[i
] = parent_opt
? xstrdup (parent_opt
) : NULL
;
485 memcpy (m_int_options
,
486 parent_ctxt
->m_int_options
,
487 sizeof (m_int_options
));
488 memcpy (m_bool_options
,
489 parent_ctxt
->m_bool_options
,
490 sizeof (m_bool_options
));
491 set_logger (parent_ctxt
->get_logger ());
495 memset (m_str_options
, 0, sizeof (m_str_options
));
496 memset (m_int_options
, 0, sizeof (m_int_options
));
497 memset (m_bool_options
, 0, sizeof (m_bool_options
));
500 memset (m_basic_types
, 0, sizeof (m_basic_types
));
503 /* The destructor for gcc::jit::recording::context, implicitly used by
504 gcc_jit_context_release. */
506 recording::context::~context ()
508 JIT_LOG_SCOPE (get_logger ());
511 FOR_EACH_VEC_ELT (m_mementos
, i
, m
)
516 for (i
= 0; i
< GCC_JIT_NUM_STR_OPTIONS
; ++i
)
517 free (m_str_options
[i
]);
519 if (m_builtins_manager
)
520 delete m_builtins_manager
;
522 if (m_owns_first_error_str
)
523 free (m_first_error_str
);
525 if (m_owns_last_error_str
)
526 if (m_last_error_str
!= m_first_error_str
)
527 free (m_last_error_str
);
530 /* Add the given mememto to the list of those tracked by this
531 gcc::jit::recording::context, so that e.g. it can be deleted
532 when this context is released. */
535 recording::context::record (memento
*m
)
539 m_mementos
.safe_push (m
);
542 /* Replay this context (and any parents) into the given replayer. */
545 recording::context::replay_into (replayer
*r
)
547 JIT_LOG_SCOPE (get_logger ());
551 /* If we have a parent context, we must replay it. This will
552 recursively walk backwards up the historical tree, then replay things
553 forwards "in historical order", starting with the ultimate parent
554 context, until we reach the "this" context.
556 Note that we fully replay the parent, then fully replay the child,
557 which means that inter-context references can only exist from child
558 to parent, not the other way around.
560 All of this replaying is suboptimal - it would be better to do the
561 work for the parent context *once*, rather than replaying the parent
562 every time we replay each child. However, fixing this requires deep
563 surgery to lifetime-management: we'd need every context family tree
564 to have its own GC heap, and to initialize the GCC code to use that
565 heap (with a mutex on such a heap). */
567 m_parent_ctxt
->replay_into (r
);
569 if (r
->errors_occurred ())
572 /* Replay this context's saved operations into r. */
573 FOR_EACH_VEC_ELT (m_mementos
, i
, m
)
575 /* Disabled low-level debugging, here if we need it: print what
577 Note that the calls to get_debug_string might lead to more
578 mementos being created for the strings.
579 This can also be used to exercise the debug_string
582 printf ("context %p replaying (%p): %s\n",
583 (void *)this, (void *)m
, m
->get_debug_string ());
587 if (r
->errors_occurred ())
592 /* During a playback, we associate objects from the recording with
593 their counterparts during this playback.
595 For simplicity, we store this within the recording objects.
597 The following method cleans away these associations, to ensure that
598 we never have out-of-date associations lingering on subsequent
599 playbacks (the objects pointed to are GC-managed, but the
600 recording objects don't own refs to them). */
603 recording::context::disassociate_from_playback ()
605 JIT_LOG_SCOPE (get_logger ());
610 m_parent_ctxt
->disassociate_from_playback ();
612 FOR_EACH_VEC_ELT (m_mementos
, i
, m
)
614 m
->set_playback_obj (NULL
);
618 /* Create a recording::string instance and add it to this context's list
621 This creates a fresh copy of the given 0-terminated buffer. */
624 recording::context::new_string (const char *text
)
629 recording::string
*result
= new string (this, text
);
634 /* Create a recording::location instance and add it to this context's
637 Implements the post-error-checking part of
638 gcc_jit_context_new_location. */
640 recording::location
*
641 recording::context::new_location (const char *filename
,
644 bool created_by_user
)
646 recording::location
*result
=
647 new recording::location (this,
648 new_string (filename
),
655 /* If we haven't seen this enum value yet, create a recording::type
656 instance and add it to this context's list of mementos.
658 If we have seen it before, reuse our cached value, so that repeated
659 calls on the context give the same object.
661 If we have a parent context, the cache is within the ultimate
664 Implements the post-error-checking part of
665 gcc_jit_context_get_type. */
668 recording::context::get_type (enum gcc_jit_types kind
)
670 if (!m_basic_types
[kind
])
673 m_basic_types
[kind
] = m_parent_ctxt
->get_type (kind
);
676 recording::type
*result
= new memento_of_get_type (this, kind
);
678 m_basic_types
[kind
] = result
;
682 return m_basic_types
[kind
];
685 /* Get a recording::type instance for the given size and signedness.
686 This is implemented in terms of recording::context::get_type
689 Implements the post-error-checking part of
690 gcc_jit_context_get_int_type. */
693 recording::context::get_int_type (int num_bytes
, int is_signed
)
695 /* We can't use a switch here since some of the values are macros affected
696 by options; e.g. i386.h has
697 #define LONG_TYPE_SIZE (TARGET_X32 ? 32 : BITS_PER_WORD)
698 Compare with tree.c's make_or_reuse_type. Note that the _SIZE macros
699 are in bits, rather than bytes.
701 const int num_bits
= num_bytes
* 8;
702 if (num_bits
== INT_TYPE_SIZE
)
703 return get_type (is_signed
705 : GCC_JIT_TYPE_UNSIGNED_INT
);
706 if (num_bits
== CHAR_TYPE_SIZE
)
707 return get_type (is_signed
708 ? GCC_JIT_TYPE_SIGNED_CHAR
709 : GCC_JIT_TYPE_UNSIGNED_CHAR
);
710 if (num_bits
== SHORT_TYPE_SIZE
)
711 return get_type (is_signed
713 : GCC_JIT_TYPE_UNSIGNED_SHORT
);
714 if (num_bits
== LONG_TYPE_SIZE
)
715 return get_type (is_signed
717 : GCC_JIT_TYPE_UNSIGNED_LONG
);
718 if (num_bits
== LONG_LONG_TYPE_SIZE
)
719 return get_type (is_signed
720 ? GCC_JIT_TYPE_LONG_LONG
721 : GCC_JIT_TYPE_UNSIGNED_LONG_LONG
);
723 /* Some other size, not corresponding to the C int types. */
724 /* To be written: support arbitrary other sizes, sharing by
725 memoizing at the recording::context level? */
729 /* Create a recording::type instance and add it to this context's list
732 Implements the post-error-checking part of
733 gcc_jit_context_new_array_type. */
736 recording::context::new_array_type (recording::location
*loc
,
737 recording::type
*element_type
,
740 if (struct_
*s
= element_type
->dyn_cast_struct ())
741 if (!s
->get_fields ())
744 "cannot create an array of type %s"
745 " until the fields have been set",
746 s
->get_name ()->c_str ());
749 recording::type
*result
=
750 new recording::array_type (this, loc
, element_type
, num_elements
);
755 /* Create a recording::field instance and add it to this context's list
758 Implements the post-error-checking part of
759 gcc_jit_context_new_field. */
762 recording::context::new_field (recording::location
*loc
,
763 recording::type
*type
,
766 recording::field
*result
=
767 new recording::field (this, loc
, type
, new_string (name
));
772 /* Create a recording::struct_ instance and add it to this context's
773 list of mementos and list of compound types.
775 Implements the post-error-checking part of
776 gcc_jit_context_new_struct_type. */
779 recording::context::new_struct_type (recording::location
*loc
,
782 recording::struct_
*result
= new struct_ (this, loc
, new_string (name
));
784 m_compound_types
.safe_push (result
);
788 /* Create a recording::union_ instance and add it to this context's
789 list of mementos and list of compound types.
791 Implements the first post-error-checking part of
792 gcc_jit_context_new_union_type. */
795 recording::context::new_union_type (recording::location
*loc
,
798 recording::union_
*result
= new union_ (this, loc
, new_string (name
));
800 m_compound_types
.safe_push (result
);
804 /* Create a recording::function_type instance and add it to this context's
807 Used by new_function_ptr_type and by builtins_manager::make_fn_type. */
809 recording::function_type
*
810 recording::context::new_function_type (recording::type
*return_type
,
812 recording::type
**param_types
,
815 recording::function_type
*fn_type
816 = new function_type (this,
825 /* Create a recording::type instance and add it to this context's list
828 Implements the post-error-checking part of
829 gcc_jit_context_new_function_ptr_type. */
832 recording::context::new_function_ptr_type (recording::location
*, /* unused loc */
833 recording::type
*return_type
,
835 recording::type
**param_types
,
838 recording::function_type
*fn_type
839 = new_function_type (return_type
,
844 /* Return a pointer-type to the the function type. */
845 return fn_type
->get_pointer ();
848 /* Create a recording::param instance and add it to this context's list
851 Implements the post-error-checking part of
852 gcc_jit_context_new_param. */
855 recording::context::new_param (recording::location
*loc
,
856 recording::type
*type
,
859 recording::param
*result
= new recording::param (this, loc
, type
, new_string (name
));
864 /* Create a recording::function instance and add it to this context's list
865 of mementos and list of functions.
867 Implements the post-error-checking part of
868 gcc_jit_context_new_function. */
870 recording::function
*
871 recording::context::new_function (recording::location
*loc
,
872 enum gcc_jit_function_kind kind
,
873 recording::type
*return_type
,
876 recording::param
**params
,
878 enum built_in_function builtin_id
)
880 recording::function
*result
=
881 new recording::function (this,
882 loc
, kind
, return_type
,
884 num_params
, params
, is_variadic
,
887 m_functions
.safe_push (result
);
892 /* Locate the builtins_manager (if any) for this family of contexts,
893 creating it if it doesn't exist already.
895 All of the recording contexts in a family share one builtins_manager:
896 if we have a child context, follow the parent links to get the
897 ultimate ancestor context, and look for it/store it there. */
900 recording::context::get_builtins_manager ()
903 return m_parent_ctxt
->get_builtins_manager ();
905 if (!m_builtins_manager
)
906 m_builtins_manager
= new builtins_manager (this);
908 return m_builtins_manager
;
911 /* Get a recording::function instance, which is lazily-created and added
912 to the context's lists of mementos.
914 Implements the post-error-checking part of
915 gcc_jit_context_get_builtin_function. */
917 recording::function
*
918 recording::context::get_builtin_function (const char *name
)
920 builtins_manager
*bm
= get_builtins_manager ();
921 return bm
->get_builtin_function (name
);
924 /* Create a recording::global instance and add it to this context's list
927 Implements the post-error-checking part of
928 gcc_jit_context_new_global. */
931 recording::context::new_global (recording::location
*loc
,
932 enum gcc_jit_global_kind kind
,
933 recording::type
*type
,
936 recording::global
*result
=
937 new recording::global (this, loc
, kind
, type
, new_string (name
));
939 m_globals
.safe_push (result
);
944 /* Create a recording::memento_of_new_string_literal instance and add it
945 to this context's list of mementos.
947 Implements the post-error-checking part of
948 gcc_jit_context_new_string_literal. */
951 recording::context::new_string_literal (const char *value
)
953 recording::rvalue
*result
=
954 new memento_of_new_string_literal (this, NULL
, new_string (value
));
959 /* Create a recording::unary_op instance and add it to this context's
962 Implements the post-error-checking part of
963 gcc_jit_context_new_unary_op. */
966 recording::context::new_unary_op (recording::location
*loc
,
967 enum gcc_jit_unary_op op
,
968 recording::type
*result_type
,
969 recording::rvalue
*a
)
971 recording::rvalue
*result
=
972 new unary_op (this, loc
, op
, result_type
, a
);
977 /* Create a recording::binary_op instance and add it to this context's
980 Implements the post-error-checking part of
981 gcc_jit_context_new_binary_op. */
984 recording::context::new_binary_op (recording::location
*loc
,
985 enum gcc_jit_binary_op op
,
986 recording::type
*result_type
,
987 recording::rvalue
*a
,
988 recording::rvalue
*b
)
990 recording::rvalue
*result
=
991 new binary_op (this, loc
, op
, result_type
, a
, b
);
996 /* Create a recording::comparison instance and add it to this context's
999 Implements the post-error-checking part of
1000 gcc_jit_context_new_comparison. */
1003 recording::context::new_comparison (recording::location
*loc
,
1004 enum gcc_jit_comparison op
,
1005 recording::rvalue
*a
,
1006 recording::rvalue
*b
)
1008 recording::rvalue
*result
= new comparison (this, loc
, op
, a
, b
);
1013 /* Create a recording::cast instance and add it to this context's list
1016 Implements the post-error-checking part of
1017 gcc_jit_context_new_cast. */
1020 recording::context::new_cast (recording::location
*loc
,
1021 recording::rvalue
*expr
,
1022 recording::type
*type_
)
1024 recording::rvalue
*result
= new cast (this, loc
, expr
, type_
);
1029 /* Create a recording::call instance and add it to this context's list
1032 Implements the post-error-checking part of
1033 gcc_jit_context_new_call. */
1036 recording::context::new_call (recording::location
*loc
,
1038 int numargs
, recording::rvalue
**args
)
1040 recording::rvalue
*result
= new call (this, loc
, func
, numargs
, args
);
1045 /* Create a recording::call_through_ptr instance and add it to this
1046 context's list of mementos.
1048 Implements the post-error-checking part of
1049 gcc_jit_context_new_call_through_ptr. */
1052 recording::context::new_call_through_ptr (recording::location
*loc
,
1053 recording::rvalue
*fn_ptr
,
1055 recording::rvalue
**args
)
1057 recording::rvalue
*result
= new call_through_ptr (this, loc
, fn_ptr
, numargs
, args
);
1062 /* Create a recording::array_access instance and add it to this context's list
1065 Implements the post-error-checking part of
1066 gcc_jit_context_new_array_access. */
1069 recording::context::new_array_access (recording::location
*loc
,
1070 recording::rvalue
*ptr
,
1071 recording::rvalue
*index
)
1073 recording::lvalue
*result
= new array_access (this, loc
, ptr
, index
);
1078 /* Set the given string option for this context, or add an error if
1079 it's not recognized.
1081 Implements the post-error-checking part of
1082 gcc_jit_context_set_str_option. */
1085 recording::context::set_str_option (enum gcc_jit_str_option opt
,
1088 if (opt
< 0 || opt
>= GCC_JIT_NUM_STR_OPTIONS
)
1091 "unrecognized (enum gcc_jit_str_option) value: %i", opt
);
1094 free (m_str_options
[opt
]);
1095 m_str_options
[opt
] = value
? xstrdup (value
) : NULL
;
1096 log_str_option (opt
);
1099 /* Set the given integer option for this context, or add an error if
1100 it's not recognized.
1102 Implements the post-error-checking part of
1103 gcc_jit_context_set_int_option. */
1106 recording::context::set_int_option (enum gcc_jit_int_option opt
,
1109 if (opt
< 0 || opt
>= GCC_JIT_NUM_INT_OPTIONS
)
1112 "unrecognized (enum gcc_jit_int_option) value: %i", opt
);
1115 m_int_options
[opt
] = value
;
1116 log_int_option (opt
);
1119 /* Set the given boolean option for this context, or add an error if
1120 it's not recognized.
1122 Implements the post-error-checking part of
1123 gcc_jit_context_set_bool_option. */
1126 recording::context::set_bool_option (enum gcc_jit_bool_option opt
,
1129 if (opt
< 0 || opt
>= GCC_JIT_NUM_BOOL_OPTIONS
)
1132 "unrecognized (enum gcc_jit_bool_option) value: %i", opt
);
1135 m_bool_options
[opt
] = value
? true : false;
1136 log_bool_option (opt
);
1139 /* Add the given dumpname/out_ptr pair to this context's list of requested
1142 Implements the post-error-checking part of
1143 gcc_jit_context_enable_dump. */
1146 recording::context::enable_dump (const char *dumpname
,
1150 gcc_assert (dumpname
);
1151 gcc_assert (out_ptr
);
1153 d
.m_dumpname
= dumpname
;
1154 d
.m_out_ptr
= out_ptr
;
1156 m_requested_dumps
.safe_push (d
);
1159 /* Validate this context, and if it passes, compile it to memory
1162 Implements the post-error-checking part of
1163 gcc_jit_context_compile. */
1166 recording::context::compile ()
1168 JIT_LOG_SCOPE (get_logger ());
1174 if (errors_occurred ())
1177 /* Set up a compile_to_memory playback context. */
1178 ::gcc::jit::playback::compile_to_memory
replayer (this);
1181 replayer
.compile ();
1183 /* Get the jit::result (or NULL) from the
1184 compile_to_memory playback context. */
1185 return replayer
.get_result_obj ();
1188 /* Validate this context, and if it passes, compile it to a file
1191 Implements the post-error-checking part of
1192 gcc_jit_context_compile_to_file. */
1195 recording::context::compile_to_file (enum gcc_jit_output_kind output_kind
,
1196 const char *output_path
)
1198 JIT_LOG_SCOPE (get_logger ());
1204 if (errors_occurred ())
1207 /* Set up a compile_to_file playback context. */
1208 ::gcc::jit::playback::compile_to_file
replayer (this,
1213 replayer
.compile ();
1216 /* Format the given error using printf's conventions, print
1217 it to stderr, and add it to the context. */
1220 recording::context::add_error (location
*loc
, const char *fmt
, ...)
1224 add_error_va (loc
, fmt
, ap
);
1228 /* Format the given error using printf's conventions, print
1229 it to stderr, and add it to the context. */
1232 recording::context::add_error_va (location
*loc
, const char *fmt
, va_list ap
)
1238 JIT_LOG_SCOPE (get_logger ());
1240 vasprintf (&malloced_msg
, fmt
, ap
);
1243 errmsg
= malloced_msg
;
1244 has_ownership
= true;
1248 errmsg
= "out of memory generating error message";
1249 has_ownership
= false;
1252 get_logger ()->log ("error %i: %s", m_error_count
, errmsg
);
1254 const char *ctxt_progname
=
1255 get_str_option (GCC_JIT_STR_OPTION_PROGNAME
);
1257 ctxt_progname
= "libgccjit.so";
1260 fprintf (stderr
, "%s: %s: error: %s\n",
1262 loc
->get_debug_string (),
1265 fprintf (stderr
, "%s: error: %s\n",
1271 m_first_error_str
= const_cast <char *> (errmsg
);
1272 m_owns_first_error_str
= has_ownership
;
1275 if (m_owns_last_error_str
)
1276 if (m_last_error_str
!= m_first_error_str
)
1277 free (m_last_error_str
);
1278 m_last_error_str
= const_cast <char *> (errmsg
);
1279 m_owns_last_error_str
= has_ownership
;
1284 /* Get the message for the first error that occurred on this context, or
1285 NULL if no errors have occurred on it.
1287 Implements the post-error-checking part of
1288 gcc_jit_context_get_first_error. */
1291 recording::context::get_first_error () const
1293 return m_first_error_str
;
1296 /* Get the message for the last error that occurred on this context, or
1297 NULL if no errors have occurred on it.
1299 Implements the post-error-checking part of
1300 gcc_jit_context_get_last_error. */
1303 recording::context::get_last_error () const
1305 return m_last_error_str
;
1308 /* Lazily generate and record a recording::type representing an opaque
1309 struct named "FILE".
1311 For use if client code tries to dereference the result of
1312 get_type (GCC_JIT_TYPE_FILE_PTR). */
1315 recording::context::get_opaque_FILE_type ()
1318 m_FILE_type
= new_struct_type (NULL
, "FILE");
1322 /* Dump a C-like representation of the given context to the given path.
1323 If UPDATE_LOCATIONS is true, update the locations within the
1324 context's mementos to point to the dumpfile.
1326 Implements the post-error-checking part of
1327 gcc_jit_context_dump_to_file. */
1330 recording::context::dump_to_file (const char *path
, bool update_locations
)
1333 dump
d (*this, path
, update_locations
);
1335 /* Forward declaration of structs and unions. */
1337 FOR_EACH_VEC_ELT (m_compound_types
, i
, st
)
1339 d
.write ("%s;\n\n", st
->get_debug_string ());
1342 /* Content of structs, where set. */
1343 FOR_EACH_VEC_ELT (m_compound_types
, i
, st
)
1344 if (st
->get_fields ())
1346 st
->get_fields ()->write_to_dump (d
);
1352 FOR_EACH_VEC_ELT (m_globals
, i
, g
)
1354 g
->write_to_dump (d
);
1356 if (!m_globals
.is_empty ())
1360 FOR_EACH_VEC_ELT (m_functions
, i
, fn
)
1362 fn
->write_to_dump (d
);
1366 static const char * const
1367 str_option_reproducer_strings
[GCC_JIT_NUM_STR_OPTIONS
] = {
1368 "GCC_JIT_STR_OPTION_PROGNAME"
1371 static const char * const
1372 int_option_reproducer_strings
[GCC_JIT_NUM_INT_OPTIONS
] = {
1373 "GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL"
1376 static const char * const
1377 bool_option_reproducer_strings
[GCC_JIT_NUM_BOOL_OPTIONS
] = {
1378 "GCC_JIT_BOOL_OPTION_DEBUGINFO",
1379 "GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE",
1380 "GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE",
1381 "GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE",
1382 "GCC_JIT_BOOL_OPTION_DUMP_SUMMARY",
1383 "GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING",
1384 "GCC_JIT_BOOL_OPTION_SELFCHECK_GC",
1385 "GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES"
1389 /* Write the current value of all options to the log file (if any). */
1392 recording::context::log_all_options () const
1399 for (opt_idx
= 0; opt_idx
< GCC_JIT_NUM_STR_OPTIONS
; opt_idx
++)
1400 log_str_option ((enum gcc_jit_str_option
)opt_idx
);
1402 for (opt_idx
= 0; opt_idx
< GCC_JIT_NUM_INT_OPTIONS
; opt_idx
++)
1403 log_int_option ((enum gcc_jit_int_option
)opt_idx
);
1405 for (opt_idx
= 0; opt_idx
< GCC_JIT_NUM_BOOL_OPTIONS
; opt_idx
++)
1406 log_bool_option ((enum gcc_jit_bool_option
)opt_idx
);
1409 /* Write the current value of the given string option to the
1410 log file (if any). */
1413 recording::context::log_str_option (enum gcc_jit_str_option opt
) const
1415 gcc_assert (opt
< GCC_JIT_NUM_STR_OPTIONS
);
1418 if (m_str_options
[opt
])
1420 str_option_reproducer_strings
[opt
],
1421 m_str_options
[opt
]);
1424 str_option_reproducer_strings
[opt
]);
1428 /* Write the current value of the given int option to the
1429 log file (if any). */
1432 recording::context::log_int_option (enum gcc_jit_int_option opt
) const
1434 gcc_assert (opt
< GCC_JIT_NUM_INT_OPTIONS
);
1437 int_option_reproducer_strings
[opt
],
1438 m_int_options
[opt
]);
1441 /* Write the current value of the given bool option to the
1442 log file (if any). */
1445 recording::context::log_bool_option (enum gcc_jit_bool_option opt
) const
1447 gcc_assert (opt
< GCC_JIT_NUM_BOOL_OPTIONS
);
1450 bool_option_reproducer_strings
[opt
],
1451 m_bool_options
[opt
] ? "true" : "false");
1454 /* Write C source code to PATH that attempts to replay the API
1455 calls made to this context (and its parents), for use in
1456 minimizing test cases for libgccjit.
1458 Implements the post-error-checking part of
1459 gcc_jit_context_dump_reproducer_to_file. */
1462 recording::context::dump_reproducer_to_file (const char *path
)
1464 JIT_LOG_SCOPE (get_logger ());
1465 reproducer
r (*this, path
);
1467 /* Generate the "ancestry" of this context, as a list. */
1468 auto_vec
<context
*> ascending_contexts
;
1469 for (context
*ctxt
= this; ctxt
; ctxt
= ctxt
->m_parent_ctxt
)
1470 ascending_contexts
.safe_push (ctxt
);
1472 /* Reverse the list, giving a list of contexts from
1473 top-most parent context down through to youngest child context.
1474 We will use this list as the parameters of the functions in
1475 our generated file. */
1476 unsigned num_ctxts
= ascending_contexts
.length ();
1477 auto_vec
<context
*> contexts (num_ctxts
);
1478 for (unsigned i
= 0; i
< num_ctxts
; i
++)
1479 contexts
.safe_push (ascending_contexts
[num_ctxts
- (i
+ 1)]);
1481 /* contexts[0] should be the top-level context. */
1482 gcc_assert (contexts
[0]);
1483 gcc_assert (contexts
[0]->m_toplevel_ctxt
== contexts
[0]);
1485 /* The final element in contexts should be "this". */
1486 gcc_assert (contexts
[contexts
.length () - 1] == this);
1487 gcc_assert (contexts
[contexts
.length () - 1]->m_toplevel_ctxt
1490 r
.write ("/* This code was autogenerated by"
1491 " gcc_jit_context_dump_reproducer_to_file.\n\n");
1492 print_version (r
.get_file (), " ", false);
1494 r
.write ("#include <libgccjit.h>\n\n");
1495 r
.write ("static void\nset_options (");
1496 r
.write_params (contexts
);
1498 r
.write ("static void\ncreate_code (");
1499 r
.write_params (contexts
);
1501 r
.write ("int\nmain (int argc, const char **argv)\n");
1503 for (unsigned i
= 0; i
< num_ctxts
; i
++)
1504 r
.write (" gcc_jit_context *%s;\n",
1505 r
.get_identifier (contexts
[i
]));
1506 r
.write (" gcc_jit_result *result;\n"
1509 /* Create the contexts.
1510 The top-level context is acquired from a clean slate, the others as
1511 children of the prior context. */
1512 r
.write (" %s = gcc_jit_context_acquire ();\n",
1513 r
.get_identifier (contexts
[0]));
1514 for (unsigned i
= 1; i
< num_ctxts
; i
++)
1515 r
.write (" %s = gcc_jit_context_new_child_context (%s);\n",
1516 r
.get_identifier (contexts
[i
]),
1517 r
.get_identifier (contexts
[i
- 1]));
1518 r
.write (" set_options (");
1519 r
.write_args (contexts
);
1521 r
.write (" create_code (");
1522 r
.write_args (contexts
);
1525 r
.write (" result = gcc_jit_context_compile (%s);\n",
1526 r
.get_identifier (this));
1528 for (unsigned i
= num_ctxts
; i
> 0; i
--)
1529 r
.write (" gcc_jit_context_release (%s);\n",
1530 r
.get_identifier (contexts
[i
- 1]));
1532 r
.write (" gcc_jit_result_release (result);\n"
1536 /* Define (char *) variables for use in calls to
1537 gcc_jit_context_enable_dump. */
1538 for (unsigned ctxt_idx
= 0; ctxt_idx
< num_ctxts
; ctxt_idx
++)
1540 if (m_requested_dumps
.length ())
1542 r
.write ("/* Requested dumps for %s. */\n",
1543 r
.get_identifier (contexts
[ctxt_idx
]));
1544 for (unsigned i
= 0; i
< m_requested_dumps
.length (); i
++)
1545 r
.write ("static char *dump_%p;\n",
1546 (void *)&m_requested_dumps
[i
]);
1551 /* Write out values of options. */
1552 r
.write ("static void\nset_options (");
1553 r
.write_params (contexts
);
1555 for (unsigned ctxt_idx
= 0; ctxt_idx
< num_ctxts
; ctxt_idx
++)
1560 r
.write (" /* Set options for %s. */\n",
1561 r
.get_identifier (contexts
[ctxt_idx
]));
1563 r
.write (" /* String options. */\n");
1564 for (int opt_idx
= 0; opt_idx
< GCC_JIT_NUM_STR_OPTIONS
; opt_idx
++)
1565 r
.write (" gcc_jit_context_set_str_option (%s,\n"
1568 r
.get_identifier (contexts
[ctxt_idx
]),
1569 str_option_reproducer_strings
[opt_idx
],
1570 m_str_options
[opt_idx
] ? m_str_options
[opt_idx
] : "NULL");
1571 r
.write (" /* Int options. */\n");
1572 for (int opt_idx
= 0; opt_idx
< GCC_JIT_NUM_INT_OPTIONS
; opt_idx
++)
1573 r
.write (" gcc_jit_context_set_int_option (%s,\n"
1576 r
.get_identifier (contexts
[ctxt_idx
]),
1577 int_option_reproducer_strings
[opt_idx
],
1578 m_int_options
[opt_idx
]);
1579 r
.write (" /* Boolean options. */\n");
1580 for (int opt_idx
= 0; opt_idx
< GCC_JIT_NUM_BOOL_OPTIONS
; opt_idx
++)
1581 r
.write (" gcc_jit_context_set_bool_option (%s,\n"
1584 r
.get_identifier (contexts
[ctxt_idx
]),
1585 bool_option_reproducer_strings
[opt_idx
],
1586 m_bool_options
[opt_idx
]);
1588 if (m_requested_dumps
.length ())
1590 r
.write (" /* Requested dumps. */\n");
1591 /* Dumpfiles that were requested via gcc_jit_context_enable_dump. */
1592 for (unsigned i
= 0; i
< m_requested_dumps
.length (); i
++)
1594 r
.write (" gcc_jit_context_enable_dump (%s,\n"
1597 r
.get_identifier (contexts
[ctxt_idx
]),
1598 m_requested_dumps
[i
].m_dumpname
,
1599 (void *)&m_requested_dumps
[i
]);
1605 r
.write ("static void\ncreate_code (");
1606 r
.write_params (contexts
);
1609 for (unsigned ctxt_idx
= 0; ctxt_idx
< num_ctxts
; ctxt_idx
++)
1616 r
.write (" /* Replay of API calls for %s. */\n",
1617 r
.get_identifier (contexts
[ctxt_idx
]));
1618 FOR_EACH_VEC_ELT (contexts
[ctxt_idx
]->m_mementos
, i
, m
)
1619 m
->write_reproducer (r
);
1624 /* Copy the requested dumps within this context and all ancestors into
1628 recording::context::get_all_requested_dumps (vec
<recording::requested_dump
> *out
)
1631 m_parent_ctxt
->get_all_requested_dumps (out
);
1633 out
->reserve (m_requested_dumps
.length ());
1634 out
->splice (m_requested_dumps
);
1637 /* This is a pre-compilation check for the context (and any parents).
1639 Detect errors within the context, adding errors if any are found. */
1642 recording::context::validate ()
1644 JIT_LOG_SCOPE (get_logger ());
1647 m_parent_ctxt
->validate ();
1651 FOR_EACH_VEC_ELT (m_functions
, i
, fn
)
1655 /* The implementation of class gcc::jit::recording::memento. */
1657 /* Get a (const char *) debug description of the given memento, by
1658 calling the pure-virtual make_debug_string hook, caching the
1661 It is intended that this should only be called in debugging and
1662 error-handling paths, so this doesn't need to be particularly
1666 recording::memento::get_debug_string ()
1668 if (!m_debug_string
)
1669 m_debug_string
= make_debug_string ();
1670 return m_debug_string
->c_str ();
1673 /* Default implementation of recording::memento::write_to_dump, writing
1674 an indented form of the memento's debug string to the dump. */
1677 recording::memento::write_to_dump (dump
&d
)
1679 d
.write(" %s\n", get_debug_string ());
1682 /* The implementation of class gcc::jit::recording::string. */
1684 /* Constructor for gcc::jit::recording::string::string, allocating a
1685 copy of the given text using new char[]. */
1687 recording::string::string (context
*ctxt
, const char *text
)
1690 m_len
= strlen (text
);
1691 m_buffer
= new char[m_len
+ 1];
1692 strcpy (m_buffer
, text
);
1695 /* Destructor for gcc::jit::recording::string::string. */
1697 recording::string::~string ()
1702 /* Function for making gcc::jit::recording::string instances on a
1703 context via printf-style formatting.
1705 It is intended that this should only be called in debugging and
1706 error-handling paths, so this doesn't need to be particularly
1707 optimized, hence the double-copy of the string is acceptable. */
1710 recording::string::from_printf (context
*ctxt
, const char *fmt
, ...)
1714 recording::string
*result
;
1717 vasprintf (&buf
, fmt
, ap
);
1722 ctxt
->add_error (NULL
, "malloc failure");
1726 result
= ctxt
->new_string (buf
);
1731 /* Implementation of recording::memento::make_debug_string for strings,
1732 wrapping the given string in quotes and escaping as necessary. */
1735 recording::string::make_debug_string ()
1737 /* Hack to avoid infinite recursion into strings when logging all
1738 mementos: don't re-escape strings: */
1739 if (m_buffer
[0] == '"')
1742 /* Wrap in quotes and do escaping etc */
1744 size_t sz
= (1 /* opening quote */
1745 + (m_len
* 2) /* each char might get escaped */
1746 + 1 /* closing quote */
1747 + 1); /* nil termintator */
1748 char *tmp
= new char[sz
];
1751 #define APPEND(CH) do { gcc_assert (len < sz); tmp[len++] = (CH); } while (0)
1752 APPEND('"'); /* opening quote */
1753 for (size_t i
= 0; i
< m_len
; i
++)
1755 char ch
= m_buffer
[i
];
1756 if (ch
== '\t' || ch
== '\n' || ch
== '\\' || ch
== '"')
1760 APPEND('"'); /* closing quote */
1762 tmp
[len
] = '\0'; /* nil termintator */
1764 string
*result
= m_ctxt
->new_string (tmp
);
1770 /* Implementation of recording::memento::write_reproducer for strings. */
1773 recording::string::write_reproducer (reproducer
&)
1778 /* The implementation of class gcc::jit::recording::location. */
1780 /* Implementation of recording::memento::replay_into for locations.
1782 Create a new playback::location and store it into the
1783 recording::location's m_playback_obj field. */
1786 recording::location::replay_into (replayer
*r
)
1788 m_playback_obj
= r
->new_location (this,
1789 m_filename
->c_str (),
1794 /* Implementation of recording::memento::make_debug_string for locations,
1795 turning them into the usual form:
1796 FILENAME:LINE:COLUMN
1797 like we do when emitting diagnostics. */
1800 recording::location::make_debug_string ()
1802 return string::from_printf (m_ctxt
,
1804 m_filename
->c_str (), m_line
, m_column
);
1807 /* Implementation of recording::memento::write_reproducer for locations. */
1810 recording::location::write_reproducer (reproducer
&r
)
1812 const char *id
= r
.make_identifier (this, "loc");
1813 r
.write (" gcc_jit_location *%s =\n"
1814 " gcc_jit_context_new_location (%s, /* gcc_jit_context *ctxt */\n"
1815 " %s, /* const char *filename */\n"
1816 " %i, /* int line */\n"
1817 " %i);/* int column */\n",
1819 r
.get_identifier (get_context ()),
1820 m_filename
->get_debug_string (),
1824 /* The implementation of class gcc::jit::recording::type. */
1826 /* Given a type T, get the type T*.
1828 If this doesn't already exist, generate a new memento_of_get_pointer
1829 instance and add it to this type's context's list of mementos.
1831 Otherwise, use the cached type.
1833 Implements the post-error-checking part of
1834 gcc_jit_type_get_pointer. */
1837 recording::type::get_pointer ()
1839 if (!m_pointer_to_this_type
)
1841 m_pointer_to_this_type
= new memento_of_get_pointer (this);
1842 m_ctxt
->record (m_pointer_to_this_type
);
1844 return m_pointer_to_this_type
;
1847 /* Given a type T, get the type const T.
1849 Implements the post-error-checking part of
1850 gcc_jit_type_get_const. */
1853 recording::type::get_const ()
1855 recording::type
*result
= new memento_of_get_const (this);
1856 m_ctxt
->record (result
);
1860 /* Given a type T, get the type volatile T.
1862 Implements the post-error-checking part of
1863 gcc_jit_type_get_volatile. */
1866 recording::type::get_volatile ()
1868 recording::type
*result
= new memento_of_get_volatile (this);
1869 m_ctxt
->record (result
);
1874 recording::type::access_as_type (reproducer
&r
)
1876 return r
.get_identifier (this);
1879 /* Implementation of pure virtual hook recording::type::dereference for
1880 recording::memento_of_get_type. */
1883 recording::memento_of_get_type::dereference ()
1887 default: gcc_unreachable ();
1889 case GCC_JIT_TYPE_VOID
:
1892 case GCC_JIT_TYPE_VOID_PTR
:
1893 return m_ctxt
->get_type (GCC_JIT_TYPE_VOID
);
1895 case GCC_JIT_TYPE_BOOL
:
1896 case GCC_JIT_TYPE_CHAR
:
1897 case GCC_JIT_TYPE_SIGNED_CHAR
:
1898 case GCC_JIT_TYPE_UNSIGNED_CHAR
:
1899 case GCC_JIT_TYPE_SHORT
:
1900 case GCC_JIT_TYPE_UNSIGNED_SHORT
:
1901 case GCC_JIT_TYPE_INT
:
1902 case GCC_JIT_TYPE_UNSIGNED_INT
:
1903 case GCC_JIT_TYPE_LONG
:
1904 case GCC_JIT_TYPE_UNSIGNED_LONG
:
1905 case GCC_JIT_TYPE_LONG_LONG
:
1906 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG
:
1907 case GCC_JIT_TYPE_FLOAT
:
1908 case GCC_JIT_TYPE_DOUBLE
:
1909 case GCC_JIT_TYPE_LONG_DOUBLE
:
1910 case GCC_JIT_TYPE_COMPLEX_FLOAT
:
1911 case GCC_JIT_TYPE_COMPLEX_DOUBLE
:
1912 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE
:
1913 /* Not a pointer: */
1916 case GCC_JIT_TYPE_CONST_CHAR_PTR
:
1917 return m_ctxt
->get_type (GCC_JIT_TYPE_CHAR
)->get_const ();
1919 case GCC_JIT_TYPE_SIZE_T
:
1920 /* Not a pointer: */
1923 case GCC_JIT_TYPE_FILE_PTR
:
1924 /* Give the client code back an opaque "struct FILE". */
1925 return m_ctxt
->get_opaque_FILE_type ();
1929 /* Implementation of pure virtual hook recording::type::is_int for
1930 recording::memento_of_get_type. */
1933 recording::memento_of_get_type::is_int () const
1937 default: gcc_unreachable ();
1939 case GCC_JIT_TYPE_VOID
:
1942 case GCC_JIT_TYPE_VOID_PTR
:
1945 case GCC_JIT_TYPE_BOOL
:
1948 case GCC_JIT_TYPE_CHAR
:
1949 case GCC_JIT_TYPE_SIGNED_CHAR
:
1950 case GCC_JIT_TYPE_UNSIGNED_CHAR
:
1951 case GCC_JIT_TYPE_SHORT
:
1952 case GCC_JIT_TYPE_UNSIGNED_SHORT
:
1953 case GCC_JIT_TYPE_INT
:
1954 case GCC_JIT_TYPE_UNSIGNED_INT
:
1955 case GCC_JIT_TYPE_LONG
:
1956 case GCC_JIT_TYPE_UNSIGNED_LONG
:
1957 case GCC_JIT_TYPE_LONG_LONG
:
1958 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG
:
1961 case GCC_JIT_TYPE_FLOAT
:
1962 case GCC_JIT_TYPE_DOUBLE
:
1963 case GCC_JIT_TYPE_LONG_DOUBLE
:
1966 case GCC_JIT_TYPE_CONST_CHAR_PTR
:
1969 case GCC_JIT_TYPE_SIZE_T
:
1972 case GCC_JIT_TYPE_FILE_PTR
:
1975 case GCC_JIT_TYPE_COMPLEX_FLOAT
:
1976 case GCC_JIT_TYPE_COMPLEX_DOUBLE
:
1977 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE
:
1982 /* Implementation of pure virtual hook recording::type::is_float for
1983 recording::memento_of_get_type. */
1986 recording::memento_of_get_type::is_float () const
1990 default: gcc_unreachable ();
1992 case GCC_JIT_TYPE_VOID
:
1995 case GCC_JIT_TYPE_VOID_PTR
:
1998 case GCC_JIT_TYPE_BOOL
:
2001 case GCC_JIT_TYPE_CHAR
:
2002 case GCC_JIT_TYPE_SIGNED_CHAR
:
2003 case GCC_JIT_TYPE_UNSIGNED_CHAR
:
2004 case GCC_JIT_TYPE_SHORT
:
2005 case GCC_JIT_TYPE_UNSIGNED_SHORT
:
2006 case GCC_JIT_TYPE_INT
:
2007 case GCC_JIT_TYPE_UNSIGNED_INT
:
2008 case GCC_JIT_TYPE_LONG
:
2009 case GCC_JIT_TYPE_UNSIGNED_LONG
:
2010 case GCC_JIT_TYPE_LONG_LONG
:
2011 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG
:
2014 case GCC_JIT_TYPE_FLOAT
:
2015 case GCC_JIT_TYPE_DOUBLE
:
2016 case GCC_JIT_TYPE_LONG_DOUBLE
:
2019 case GCC_JIT_TYPE_CONST_CHAR_PTR
:
2022 case GCC_JIT_TYPE_SIZE_T
:
2025 case GCC_JIT_TYPE_FILE_PTR
:
2028 case GCC_JIT_TYPE_COMPLEX_FLOAT
:
2029 case GCC_JIT_TYPE_COMPLEX_DOUBLE
:
2030 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE
:
2035 /* Implementation of pure virtual hook recording::type::is_bool for
2036 recording::memento_of_get_type. */
2039 recording::memento_of_get_type::is_bool () const
2043 default: gcc_unreachable ();
2045 case GCC_JIT_TYPE_VOID
:
2048 case GCC_JIT_TYPE_VOID_PTR
:
2051 case GCC_JIT_TYPE_BOOL
:
2054 case GCC_JIT_TYPE_CHAR
:
2055 case GCC_JIT_TYPE_SIGNED_CHAR
:
2056 case GCC_JIT_TYPE_UNSIGNED_CHAR
:
2057 case GCC_JIT_TYPE_SHORT
:
2058 case GCC_JIT_TYPE_UNSIGNED_SHORT
:
2059 case GCC_JIT_TYPE_INT
:
2060 case GCC_JIT_TYPE_UNSIGNED_INT
:
2061 case GCC_JIT_TYPE_LONG
:
2062 case GCC_JIT_TYPE_UNSIGNED_LONG
:
2063 case GCC_JIT_TYPE_LONG_LONG
:
2064 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG
:
2067 case GCC_JIT_TYPE_FLOAT
:
2068 case GCC_JIT_TYPE_DOUBLE
:
2069 case GCC_JIT_TYPE_LONG_DOUBLE
:
2072 case GCC_JIT_TYPE_CONST_CHAR_PTR
:
2075 case GCC_JIT_TYPE_SIZE_T
:
2078 case GCC_JIT_TYPE_FILE_PTR
:
2081 case GCC_JIT_TYPE_COMPLEX_FLOAT
:
2082 case GCC_JIT_TYPE_COMPLEX_DOUBLE
:
2083 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE
:
2088 /* Implementation of pure virtual hook recording::memento::replay_into
2089 for recording::memento_of_get_type. */
2092 recording::memento_of_get_type::replay_into (replayer
*r
)
2094 set_playback_obj (r
->get_type (m_kind
));
2097 /* The implementation of class gcc::jit::recording::memento_of_get_type. */
2099 /* Descriptive strings for each of enum gcc_jit_types. */
2101 static const char * const get_type_strings
[] = {
2102 "void", /* GCC_JIT_TYPE_VOID */
2103 "void *", /* GCC_JIT_TYPE_VOID_PTR */
2105 "bool", /* GCC_JIT_TYPE_BOOL */
2107 "char", /* GCC_JIT_TYPE_CHAR */
2108 "signed char", /* GCC_JIT_TYPE_SIGNED_CHAR */
2109 "unsigned char", /* GCC_JIT_TYPE_UNSIGNED_CHAR */
2111 "short", /* GCC_JIT_TYPE_SHORT */
2112 "unsigned short", /* GCC_JIT_TYPE_UNSIGNED_SHORT */
2114 "int", /* GCC_JIT_TYPE_INT */
2115 "unsigned int", /* GCC_JIT_TYPE_UNSIGNED_INT */
2117 "long", /* GCC_JIT_TYPE_LONG */
2118 "unsigned long", /* GCC_JIT_TYPE_UNSIGNED_LONG, */
2120 "long long", /* GCC_JIT_TYPE_LONG_LONG */
2121 "unsigned long long", /* GCC_JIT_TYPE_UNSIGNED_LONG_LONG */
2123 "float", /* GCC_JIT_TYPE_FLOAT */
2124 "double", /* GCC_JIT_TYPE_DOUBLE */
2125 "long double", /* GCC_JIT_TYPE_LONG_DOUBLE */
2127 "const char *", /* GCC_JIT_TYPE_CONST_CHAR_PTR */
2129 "size_t", /* GCC_JIT_TYPE_SIZE_T */
2131 "FILE *", /* GCC_JIT_TYPE_FILE_PTR */
2133 "complex float", /* GCC_JIT_TYPE_COMPLEX_FLOAT */
2134 "complex double", /* GCC_JIT_TYPE_COMPLEX_DOUBLE */
2135 "complex long double" /* GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE */
2139 /* Implementation of recording::memento::make_debug_string for
2140 results of get_type, using a simple table of type names. */
2143 recording::memento_of_get_type::make_debug_string ()
2145 return m_ctxt
->new_string (get_type_strings
[m_kind
]);
2148 static const char * const get_type_enum_strings
[] = {
2149 "GCC_JIT_TYPE_VOID",
2150 "GCC_JIT_TYPE_VOID_PTR",
2151 "GCC_JIT_TYPE_BOOL",
2152 "GCC_JIT_TYPE_CHAR",
2153 "GCC_JIT_TYPE_SIGNED_CHAR",
2154 "GCC_JIT_TYPE_UNSIGNED_CHAR",
2155 "GCC_JIT_TYPE_SHORT",
2156 "GCC_JIT_TYPE_UNSIGNED_SHORT",
2158 "GCC_JIT_TYPE_UNSIGNED_INT",
2159 "GCC_JIT_TYPE_LONG",
2160 "GCC_JIT_TYPE_UNSIGNED_LONG",
2161 "GCC_JIT_TYPE_LONG_LONG",
2162 "GCC_JIT_TYPE_UNSIGNED_LONG_LONG",
2163 "GCC_JIT_TYPE_FLOAT",
2164 "GCC_JIT_TYPE_DOUBLE",
2165 "GCC_JIT_TYPE_LONG_DOUBLE",
2166 "GCC_JIT_TYPE_CONST_CHAR_PTR",
2167 "GCC_JIT_TYPE_SIZE_T",
2168 "GCC_JIT_TYPE_FILE_PTR",
2169 "GCC_JIT_TYPE_COMPLEX_FLOAT",
2170 "GCC_JIT_TYPE_COMPLEX_DOUBLE",
2171 "GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE"
2175 recording::memento_of_get_type::write_reproducer (reproducer
&r
)
2177 const char *id
= r
.make_identifier (this, "type");
2178 r
.write (" gcc_jit_type *%s = gcc_jit_context_get_type (%s, %s);\n",
2180 r
.get_identifier (get_context ()),
2181 get_type_enum_strings
[m_kind
]);
2184 /* The implementation of class gcc::jit::recording::memento_of_get_pointer. */
2186 /* Override of default implementation of
2187 recording::type::accepts_writes_from for get_pointer.
2189 Require a pointer type, and allowing writes to
2190 (const T *) from a (T*), but not the other way around. */
2193 recording::memento_of_get_pointer::accepts_writes_from (type
*rtype
)
2195 /* Must be a pointer type: */
2196 type
*rtype_points_to
= rtype
->is_pointer ();
2197 if (!rtype_points_to
)
2200 /* It's OK to assign to a (const T *) from a (T *). */
2201 return m_other_type
->unqualified ()
2202 ->accepts_writes_from (rtype_points_to
);
2205 /* Implementation of pure virtual hook recording::memento::replay_into
2206 for recording::memento_of_get_pointer. */
2209 recording::memento_of_get_pointer::replay_into (replayer
*)
2211 set_playback_obj (m_other_type
->playback_type ()->get_pointer ());
2214 /* Implementation of recording::memento::make_debug_string for
2215 results of get_pointer, adding " *" to the underlying type,
2216 with special-casing to handle function pointer types. */
2219 recording::memento_of_get_pointer::make_debug_string ()
2221 /* Special-case function pointer types, to put the "*" in parens between
2222 the return type and the params (for one level of dereferencing, at
2224 if (function_type
*fn_type
= m_other_type
->dyn_cast_function_type ())
2225 return fn_type
->make_debug_string_with_ptr ();
2227 return string::from_printf (m_ctxt
,
2228 "%s *", m_other_type
->get_debug_string ());
2231 /* Implementation of recording::memento::write_reproducer for get_pointer. */
2234 recording::memento_of_get_pointer::write_reproducer (reproducer
&r
)
2236 /* We need to special-case function pointer types; see the notes in
2237 recording::function_type::write_deferred_reproducer. */
2238 if (function_type
*fn_type
= m_other_type
->dyn_cast_function_type ())
2240 fn_type
->write_deferred_reproducer (r
, this);
2244 const char *id
= r
.make_identifier (this, "type");
2245 r
.write (" gcc_jit_type *%s =\n"
2246 " gcc_jit_type_get_pointer (%s);\n",
2248 r
.get_identifier_as_type (m_other_type
));
2251 /* The implementation of class gcc::jit::recording::memento_of_get_const. */
2253 /* Implementation of pure virtual hook recording::memento::replay_into
2254 for recording::memento_of_get_const. */
2257 recording::memento_of_get_const::replay_into (replayer
*)
2259 set_playback_obj (m_other_type
->playback_type ()->get_const ());
2262 /* Implementation of recording::memento::make_debug_string for
2263 results of get_const, prepending "const ". */
2266 recording::memento_of_get_const::make_debug_string ()
2268 return string::from_printf (m_ctxt
,
2269 "const %s", m_other_type
->get_debug_string ());
2272 /* Implementation of recording::memento::write_reproducer for const types. */
2275 recording::memento_of_get_const::write_reproducer (reproducer
&r
)
2277 const char *id
= r
.make_identifier (this, "type");
2278 r
.write (" gcc_jit_type *%s =\n"
2279 " gcc_jit_type_get_const (%s);\n",
2281 r
.get_identifier_as_type (m_other_type
));
2284 /* The implementation of class gcc::jit::recording::memento_of_get_volatile. */
2286 /* Implementation of pure virtual hook recording::memento::replay_into
2287 for recording::memento_of_get_volatile. */
2290 recording::memento_of_get_volatile::replay_into (replayer
*)
2292 set_playback_obj (m_other_type
->playback_type ()->get_volatile ());
2295 /* Implementation of recording::memento::make_debug_string for
2296 results of get_volatile, prepending "volatile ". */
2299 recording::memento_of_get_volatile::make_debug_string ()
2301 return string::from_printf (m_ctxt
,
2302 "volatile %s", m_other_type
->get_debug_string ());
2305 /* Implementation of recording::memento::write_reproducer for volatile
2309 recording::memento_of_get_volatile::write_reproducer (reproducer
&r
)
2311 const char *id
= r
.make_identifier (this, "type");
2312 r
.write (" gcc_jit_type *%s =\n"
2313 " gcc_jit_type_get_volatile (%s);\n",
2315 r
.get_identifier_as_type (m_other_type
));
2318 /* The implementation of class gcc::jit::recording::array_type */
2320 /* Implementation of pure virtual hook recording::type::dereference for
2321 recording::array_type. */
2324 recording::array_type::dereference ()
2326 return m_element_type
;
2329 /* Implementation of pure virtual hook recording::memento::replay_into
2330 for recording::array_type. */
2333 recording::array_type::replay_into (replayer
*r
)
2335 set_playback_obj (r
->new_array_type (playback_location (r
, m_loc
),
2336 m_element_type
->playback_type (),
2340 /* Implementation of recording::memento::make_debug_string for
2341 results of new_array_type. */
2344 recording::array_type::make_debug_string ()
2346 return string::from_printf (m_ctxt
,
2348 m_element_type
->get_debug_string (),
2352 /* Implementation of recording::memento::write_reproducer for array
2356 recording::array_type::write_reproducer (reproducer
&r
)
2358 const char *id
= r
.make_identifier (this, "array_type");
2359 r
.write (" gcc_jit_type *%s =\n"
2360 " gcc_jit_context_new_array_type (%s,\n"
2361 " %s, /* gcc_jit_location *loc */\n"
2362 " %s, /* gcc_jit_type *element_type */\n"
2363 " %i); /* int num_elements */\n",
2365 r
.get_identifier (get_context ()),
2366 r
.get_identifier (m_loc
),
2367 r
.get_identifier_as_type (m_element_type
),
2371 /* The implementation of class gcc::jit::recording::function_type */
2373 /* Constructor for gcc::jit::recording::function_type. */
2375 recording::function_type::function_type (context
*ctxt
,
2381 m_return_type (return_type
),
2383 m_is_variadic (is_variadic
)
2385 for (int i
= 0; i
< num_params
; i
++)
2386 m_param_types
.safe_push (param_types
[i
]);
2389 /* Implementation of pure virtual hook recording::type::dereference for
2390 recording::function_type. */
2393 recording::function_type::dereference ()
2398 /* Implementation of pure virtual hook recording::memento::replay_into
2399 for recording::function_type. */
2402 recording::function_type::replay_into (replayer
*r
)
2404 /* Convert m_param_types to a vec of playback type. */
2405 auto_vec
<playback::type
*> param_types
;
2407 recording::type
*type
;
2408 param_types
.create (m_param_types
.length ());
2409 FOR_EACH_VEC_ELT (m_param_types
, i
, type
)
2410 param_types
.safe_push (type
->playback_type ());
2412 set_playback_obj (r
->new_function_type (m_return_type
->playback_type (),
2417 /* Special-casing for make_debug_string for get_pointer results for
2418 handling (one level) of pointers to functions. */
2421 recording::function_type::make_debug_string_with_ptr ()
2423 return make_debug_string_with ("(*) ");
2426 /* Implementation of recording::memento::make_debug_string for
2427 results of new_function_type. */
2430 recording::function_type::make_debug_string ()
2432 return make_debug_string_with ("");
2435 /* Build a debug string representation of the form:
2437 RESULT_TYPE INSERT (PARAM_TYPES)
2439 for use when handling 0 and 1 level of indirection to this
2443 recording::function_type::make_debug_string_with (const char *insert
)
2445 /* First, build a buffer for the arguments. */
2446 /* Calculate length of said buffer. */
2447 size_t sz
= 1; /* nil terminator */
2448 for (unsigned i
= 0; i
< m_param_types
.length (); i
++)
2450 sz
+= strlen (m_param_types
[i
]->get_debug_string ());
2451 sz
+= 2; /* ", " separator */
2454 sz
+= 5; /* ", ..." separator and ellipsis */
2456 /* Now allocate and populate the buffer. */
2457 char *argbuf
= new char[sz
];
2460 for (unsigned i
= 0; i
< m_param_types
.length (); i
++)
2462 strcpy (argbuf
+ len
, m_param_types
[i
]->get_debug_string ());
2463 len
+= strlen (m_param_types
[i
]->get_debug_string ());
2464 if (i
+ 1 < m_param_types
.length ())
2466 strcpy (argbuf
+ len
, ", ");
2472 if (m_param_types
.length ())
2474 strcpy (argbuf
+ len
, ", ");
2477 strcpy (argbuf
+ len
, "...");
2482 /* ...and use it to get the string for the call as a whole. */
2483 string
*result
= string::from_printf (m_ctxt
,
2485 m_return_type
->get_debug_string (),
2494 /* Implementation of recording::memento::write_reproducer for function
2498 recording::function_type::write_reproducer (reproducer
&)
2500 /* see notes below. */
2503 /* There's a get_pointer within context::new_function_ptr_type:
2504 the type received by client code isn't the memento for the
2505 function_type, but instead the result of get_pointer on it.
2507 Hence we can't directly write a reproducer that gives function_type.
2508 Instead we special-case things within get_pointer, detecting this
2509 case, calling the following function. */
2512 recording::function_type::write_deferred_reproducer (reproducer
&r
,
2515 gcc_assert (ptr_type
);
2516 r
.make_identifier (this, "function_type");
2517 const char *ptr_id
= r
.make_identifier (ptr_type
, "ptr_to");
2518 const char *param_types_id
= r
.make_tmp_identifier ("params_for", this);
2519 r
.write (" gcc_jit_type *%s[%i] = {\n",
2521 m_param_types
.length ());
2524 FOR_EACH_VEC_ELT (m_param_types
, i
, param_type
)
2525 r
.write (" %s,\n", r
.get_identifier_as_type (param_type
));
2527 r
.write (" gcc_jit_type *%s =\n"
2528 " gcc_jit_context_new_function_ptr_type (%s, /* gcc_jit_context *ctxt */\n"
2529 " %s, /* gcc_jit_location *loc */\n"
2530 " %s, /* gcc_jit_type *return_type */\n"
2531 " %i, /* int num_params */\n"
2532 " %s, /* gcc_jit_type **param_types */\n"
2533 " %i); /* int is_variadic */\n",
2535 r
.get_identifier (get_context ()),
2536 "NULL", /* location is not stored */
2537 r
.get_identifier_as_type (m_return_type
),
2538 m_param_types
.length (),
2543 /* The implementation of class gcc::jit::recording::field. */
2545 /* Implementation of pure virtual hook recording::memento::replay_into
2546 for recording::field. */
2549 recording::field::replay_into (replayer
*r
)
2551 set_playback_obj (r
->new_field (playback_location (r
, m_loc
),
2552 m_type
->playback_type (),
2553 playback_string (m_name
)));
2556 /* Override the default implementation of
2557 recording::memento::write_to_dump. Dump each field
2558 by dumping a line of the form:
2560 so that we can build up a struct/union field-byfield. */
2563 recording::field::write_to_dump (dump
&d
)
2565 d
.write (" %s %s;\n",
2566 m_type
->get_debug_string (),
2570 /* Implementation of recording::memento::make_debug_string for
2571 results of new_field. */
2574 recording::field::make_debug_string ()
2579 /* Implementation of recording::memento::write_reproducer for fields. */
2582 recording::field::write_reproducer (reproducer
&r
)
2584 const char *id
= r
.make_identifier (this, "field");
2585 r
.write(" gcc_jit_field *%s =\n"
2586 " gcc_jit_context_new_field (%s,\n"
2587 " %s, /* gcc_jit_location *loc */\n"
2588 " %s, /* gcc_jit_type *type, */\n"
2589 " %s); /* const char *name */\n",
2591 r
.get_identifier (get_context ()),
2592 r
.get_identifier (m_loc
),
2593 r
.get_identifier_as_type (m_type
),
2594 m_name
->get_debug_string ());
2597 /* The implementation of class gcc::jit::recording::compound_type */
2599 /* The constructor for gcc::jit::recording::compound_type. */
2601 recording::compound_type::compound_type (context
*ctxt
,
2611 /* Set the fields of a compound type.
2613 Implements the post-error-checking part of
2614 gcc_jit_struct_set_fields, and is also used by
2615 gcc_jit_context_new_union_type. */
2618 recording::compound_type::set_fields (location
*loc
,
2620 field
**field_array
)
2623 gcc_assert (NULL
== m_fields
);
2625 m_fields
= new fields (this, num_fields
, field_array
);
2626 m_ctxt
->record (m_fields
);
2629 /* Implementation of pure virtual hook recording::type::dereference for
2630 recording::compound_type. */
2633 recording::compound_type::dereference ()
2635 return NULL
; /* not a pointer */
2638 /* The implementation of class gcc::jit::recording::struct_. */
2640 /* The constructor for gcc::jit::recording::struct_. */
2642 recording::struct_::struct_ (context
*ctxt
,
2645 : compound_type (ctxt
, loc
, name
)
2649 /* Implementation of pure virtual hook recording::memento::replay_into
2650 for recording::struct_. */
2653 recording::struct_::replay_into (replayer
*r
)
2656 r
->new_compound_type (playback_location (r
, get_loc ()),
2657 get_name ()->c_str (),
2658 true /* is_struct */));
2662 recording::struct_::access_as_type (reproducer
&r
)
2664 return r
.xstrdup_printf ("gcc_jit_struct_as_type (%s)",
2665 r
.get_identifier (this));
2668 /* Implementation of recording::memento::make_debug_string for
2672 recording::struct_::make_debug_string ()
2674 return string::from_printf (m_ctxt
,
2675 "struct %s", get_name ()->c_str ());
2679 recording::struct_::write_reproducer (reproducer
&r
)
2681 const char *id
= r
.make_identifier (this, "struct");
2682 r
.write (" gcc_jit_struct *%s =\n"
2683 " gcc_jit_context_new_opaque_struct (%s,\n"
2684 " %s, /* gcc_jit_location *loc */\n"
2685 " %s); /* const char *name */\n",
2687 r
.get_identifier (get_context ()),
2688 r
.get_identifier (get_loc ()),
2689 get_name ()->get_debug_string ());
2692 /* The implementation of class gcc::jit::recording::union_. */
2694 /* The constructor for gcc::jit::recording::union_. */
2696 recording::union_::union_ (context
*ctxt
,
2699 : compound_type (ctxt
, loc
, name
)
2703 /* Implementation of pure virtual hook recording::memento::replay_into
2704 for recording::union_. */
2707 recording::union_::replay_into (replayer
*r
)
2710 r
->new_compound_type (playback_location (r
, get_loc ()),
2711 get_name ()->c_str (),
2712 false /* is_struct */));
2715 /* Implementation of recording::memento::make_debug_string for
2719 recording::union_::make_debug_string ()
2721 return string::from_printf (m_ctxt
,
2722 "union %s", get_name ()->c_str ());
2725 /* Implementation of recording::memento::write_reproducer for unions. */
2728 recording::union_::write_reproducer (reproducer
&r
)
2730 const char *id
= r
.make_identifier (this, "union");
2732 const char *fields_id
= r
.make_tmp_identifier ("fields_for", this);
2733 r
.write (" gcc_jit_field *%s[%i] = {\n",
2735 get_fields ()->length ());
2736 for (int i
= 0; i
< get_fields ()->length (); i
++)
2737 r
.write (" %s,\n", r
.get_identifier (get_fields ()->get_field (i
)));
2740 r
.write (" gcc_jit_type *%s =\n"
2741 " gcc_jit_context_new_union_type (%s,\n"
2742 " %s, /* gcc_jit_location *loc */\n"
2743 " %s, /* const char *name */\n"
2744 " %i, /* int num_fields */\n"
2745 " %s); /* gcc_jit_field **fields */\n",
2747 r
.get_identifier (get_context ()),
2748 r
.get_identifier (get_loc ()),
2749 get_name ()->get_debug_string (),
2750 get_fields ()->length (),
2754 /* The implementation of class gcc::jit::recording::fields. */
2756 /* The constructor for gcc::jit::recording::fields. */
2758 recording::fields::fields (compound_type
*struct_or_union
,
2761 : memento (struct_or_union
->m_ctxt
),
2762 m_struct_or_union (struct_or_union
),
2765 for (int i
= 0; i
< num_fields
; i
++)
2767 gcc_assert (fields
[i
]->get_container () == NULL
);
2768 fields
[i
]->set_container (m_struct_or_union
);
2769 m_fields
.safe_push (fields
[i
]);
2773 /* Implementation of pure virtual hook recording::memento::replay_into
2774 for recording::fields. */
2777 recording::fields::replay_into (replayer
*)
2779 auto_vec
<playback::field
*> playback_fields
;
2780 playback_fields
.create (m_fields
.length ());
2781 for (unsigned i
= 0; i
< m_fields
.length (); i
++)
2782 playback_fields
.safe_push (m_fields
[i
]->playback_field ());
2783 m_struct_or_union
->playback_compound_type ()->set_fields (&playback_fields
);
2786 /* Override the default implementation of
2787 recording::memento::write_to_dump by writing a union/struct
2788 declaration of this form:
2800 recording::fields::write_to_dump (dump
&d
)
2805 d
.write ("%s\n{\n", m_struct_or_union
->get_debug_string ());
2806 FOR_EACH_VEC_ELT (m_fields
, i
, f
)
2807 f
->write_to_dump (d
);
2811 /* Implementation of recording::memento::write_reproducer for the fields
2815 recording::fields::write_reproducer (reproducer
&r
)
2817 if (m_struct_or_union
)
2818 if (NULL
== m_struct_or_union
->dyn_cast_struct ())
2819 /* We have a union; the fields have already been written by
2820 union::write_reproducer. */
2823 const char *fields_id
= r
.make_identifier (this, "fields");
2824 r
.write (" gcc_jit_field *%s[%i] = {\n",
2826 m_fields
.length ());
2829 FOR_EACH_VEC_ELT (m_fields
, i
, field
)
2830 r
.write (" %s,\n", r
.get_identifier (field
));
2833 r
.write (" gcc_jit_struct_set_fields (%s, /* gcc_jit_struct *struct_type */\n"
2834 " %s, /* gcc_jit_location *loc */\n"
2835 " %i, /* int num_fields */\n"
2836 " %s); /* gcc_jit_field **fields */\n",
2837 r
.get_identifier (m_struct_or_union
),
2838 r
.get_identifier ((memento
*)NULL
),
2843 /* Implementation of recording::memento::make_debug_string for
2847 recording::fields::make_debug_string ()
2849 return string::from_printf (m_ctxt
,
2853 /* The implementation of class gcc::jit::recording::rvalue. */
2855 /* Create a recording::access_field_rvalue instance and add it to
2856 the rvalue's context's list of mementos.
2858 Implements the post-error-checking part of
2859 gcc_jit_rvalue_access_field. */
2862 recording::rvalue::access_field (recording::location
*loc
,
2865 recording::rvalue
*result
=
2866 new access_field_rvalue (m_ctxt
, loc
, this, field
);
2867 m_ctxt
->record (result
);
2871 /* Create a recording::dereference_field_rvalue instance and add it to
2872 the rvalue's context's list of mementos.
2874 Implements the post-error-checking part of
2875 gcc_jit_rvalue_dereference_field. */
2878 recording::rvalue::dereference_field (recording::location
*loc
,
2881 recording::lvalue
*result
=
2882 new dereference_field_rvalue (m_ctxt
, loc
, this, field
);
2883 m_ctxt
->record (result
);
2887 /* Create a recording::dereference_rvalue instance and add it to the
2888 rvalue's context's list of mementos.
2890 Implements the post-error-checking part of
2891 gcc_jit_rvalue_dereference. */
2894 recording::rvalue::dereference (recording::location
*loc
)
2896 recording::lvalue
*result
=
2897 new dereference_rvalue (m_ctxt
, loc
, this);
2898 m_ctxt
->record (result
);
2902 /* An rvalue visitor, for validating that every rvalue within an expression
2903 trees within "STMT" has the correct scope (e.g. no access to locals
2904 of a different function). */
2906 class rvalue_usage_validator
: public recording::rvalue_visitor
2909 rvalue_usage_validator (const char *api_funcname
,
2910 recording::context
*ctxt
,
2911 recording::statement
*stmt
);
2914 visit (recording::rvalue
*rvalue
);
2917 const char *m_api_funcname
;
2918 recording::context
*m_ctxt
;
2919 recording::statement
*m_stmt
;
2922 /* The trivial constructor for rvalue_usage_validator. */
2924 rvalue_usage_validator::rvalue_usage_validator (const char *api_funcname
,
2925 recording::context
*ctxt
,
2926 recording::statement
*stmt
)
2927 : m_api_funcname (api_funcname
),
2933 /* Verify that the given rvalue is in the correct scope. */
2936 rvalue_usage_validator::visit (recording::rvalue
*rvalue
)
2938 gcc_assert (m_stmt
->get_block ());
2939 recording::function
*stmt_scope
= m_stmt
->get_block ()->get_function ();
2941 /* Most rvalues don't have a scope (only locals and params). */
2942 if (rvalue
->get_scope ())
2944 if (rvalue
->get_scope () != stmt_scope
)
2946 (rvalue
->get_loc (),
2948 " rvalue %s (type: %s)"
2949 " has scope limited to function %s"
2950 " but was used within function %s"
2951 " (in statement: %s)",
2953 rvalue
->get_debug_string (),
2954 rvalue
->get_type ()->get_debug_string (),
2955 rvalue
->get_scope ()->get_debug_string (),
2956 stmt_scope
->get_debug_string (),
2957 m_stmt
->get_debug_string ());
2961 if (rvalue
->dyn_cast_param ())
2963 (rvalue
->get_loc (),
2965 " param %s (type: %s)"
2966 " was used within function %s"
2967 " (in statement: %s)"
2968 " but is not associated with any function",
2970 rvalue
->get_debug_string (),
2971 rvalue
->get_type ()->get_debug_string (),
2972 stmt_scope
->get_debug_string (),
2973 m_stmt
->get_debug_string ());
2977 /* Verify that it's valid to use this rvalue (and all expressions
2978 in the tree below it) within the given statement.
2980 For example, we must reject attempts to use a local from one
2981 function within a different function here, or we'll get
2982 an ICE deep inside toplev::main. */
2985 recording::rvalue::verify_valid_within_stmt (const char *api_funcname
, statement
*s
)
2987 rvalue_usage_validator
v (api_funcname
,
2991 /* Verify that it's OK to use this rvalue within s. */
2994 /* Traverse the expression tree below "this", verifying all rvalues
2996 visit_children (&v
);
2999 /* Set the scope of this rvalue to be the given function. This can only
3000 be done once on a given rvalue. */
3003 recording::rvalue::set_scope (function
*scope
)
3006 gcc_assert (NULL
== m_scope
);
3011 /* Implementation of recording::rvalue::access_as_rvalue for rvalues
3013 Instances of rvalue don't need an upcast call. */
3016 recording::rvalue::access_as_rvalue (reproducer
&r
)
3018 return r
.get_identifier (this);
3022 /* The implementation of class gcc::jit::recording::lvalue. */
3024 /* Create a recording::new_access_field_of_lvalue instance and add it to
3025 the lvalue's context's list of mementos.
3027 Implements the post-error-checking part of
3028 gcc_jit_lvalue_access_field. */
3031 recording::lvalue::access_field (recording::location
*loc
,
3034 recording::lvalue
*result
=
3035 new access_field_of_lvalue (m_ctxt
, loc
, this, field
);
3036 m_ctxt
->record (result
);
3040 /* Implementation of recording::rvalue::access_as_rvalue for lvalues.
3041 Instances of lvalue need to be wrapped in a gcc_jit_lvalue_as_rvalue
3045 recording::lvalue::access_as_rvalue (reproducer
&r
)
3047 return r
.xstrdup_printf ("gcc_jit_lvalue_as_rvalue (%s)",
3048 r
.get_identifier (this));
3051 /* Implementation of recording::lvalue::access_as_lvalue for lvalues.
3052 Instances of lvalue don't need to be upcast. */
3055 recording::lvalue::access_as_lvalue (reproducer
&r
)
3057 return r
.get_identifier (this);
3060 /* Create a recording::get_address_of_lvalue instance and add it to
3061 the lvalue's context's list of mementos.
3063 Implements the post-error-checking part of
3064 gcc_jit_lvalue_get_address. */
3067 recording::lvalue::get_address (recording::location
*loc
)
3069 recording::rvalue
*result
=
3070 new get_address_of_lvalue (m_ctxt
, loc
, this);
3071 m_ctxt
->record (result
);
3075 /* The implementation of class gcc::jit::recording::param. */
3077 /* Implementation of pure virtual hook recording::memento::replay_into
3078 for recording::param. */
3081 recording::param::replay_into (replayer
*r
)
3083 set_playback_obj (r
->new_param (playback_location (r
, m_loc
),
3084 m_type
->playback_type (),
3088 /* Implementation of recording::rvalue::access_as_rvalue for params.
3089 Instances of param need to be wrapped in a gcc_jit_param_as_rvalue
3093 recording::param::access_as_rvalue (reproducer
&r
)
3095 return r
.xstrdup_printf ("gcc_jit_param_as_rvalue (%s)",
3096 r
.get_identifier (this));
3099 /* Implementation of recording::lvalue::access_as_lvalue for params.
3100 Instances of param need to be wrapped in a gcc_jit_param_as_lvalue
3104 recording::param::access_as_lvalue (reproducer
&r
)
3106 return r
.xstrdup_printf ("gcc_jit_param_as_lvalue (%s)",
3107 r
.get_identifier (this));
3110 /* Implementation of recording::memento::write_reproducer for params. */
3113 recording::param::write_reproducer (reproducer
&r
)
3115 const char *id
= r
.make_identifier (this, "param");
3116 r
.write (" gcc_jit_param *%s =\n"
3117 " gcc_jit_context_new_param (%s,\n"
3118 " %s, /* gcc_jit_location *loc */\n"
3119 " %s, /*gcc_jit_type *type */\n"
3120 " %s); /* const char *name */\n",
3122 r
.get_identifier (get_context ()),
3123 r
.get_identifier (m_loc
),
3124 r
.get_identifier_as_type (m_type
),
3125 m_name
->get_debug_string ());
3128 /* The implementation of class gcc::jit::recording::function. */
3130 /* gcc::jit::recording::function's constructor. */
3132 recording::function::function (context
*ctxt
,
3133 recording::location
*loc
,
3134 enum gcc_jit_function_kind kind
,
3136 recording::string
*name
,
3138 recording::param
**params
,
3140 enum built_in_function builtin_id
)
3144 m_return_type (return_type
),
3147 m_is_variadic (is_variadic
),
3148 m_builtin_id (builtin_id
),
3152 for (int i
= 0; i
< num_params
; i
++)
3154 param
*param
= params
[i
];
3157 /* Associate each param with this function.
3159 Verify that the param doesn't already have a function. */
3160 if (param
->get_scope ())
3162 /* We've already rejected attempts to reuse a param between
3163 different functions (within gcc_jit_context_new_function), so
3164 if the param *does* already have a function, it must be being
3165 reused within the params array for this function. We must
3166 produce an error for this reuse (blocking the compile), since
3167 otherwise we'd have an ICE later on. */
3168 gcc_assert (this == param
->get_scope ());
3171 "gcc_jit_context_new_function:"
3172 " parameter %s (type: %s)"
3173 " is used more than once when creating function %s",
3174 param
->get_debug_string (),
3175 param
->get_type ()->get_debug_string (),
3180 /* The normal, non-error case: associate this function with the
3182 param
->set_scope (this);
3185 m_params
.safe_push (param
);
3189 /* Implementation of pure virtual hook recording::memento::replay_into
3190 for recording::function. */
3193 recording::function::replay_into (replayer
*r
)
3195 /* Convert m_params to a vec of playback param. */
3196 auto_vec
<playback::param
*> params
;
3198 recording::param
*param
;
3199 params
.create (m_params
.length ());
3200 FOR_EACH_VEC_ELT (m_params
, i
, param
)
3201 params
.safe_push (param
->playback_param ());
3203 set_playback_obj (r
->new_function (playback_location (r
, m_loc
),
3205 m_return_type
->playback_type (),
3212 /* Create a recording::local instance and add it to
3213 the functions's context's list of mementos, and to the function's
3216 Implements the post-error-checking part of
3217 gcc_jit_function_new_local. */
3220 recording::function::new_local (recording::location
*loc
,
3224 local
*result
= new local (this, loc
, type
, new_string (name
));
3225 m_ctxt
->record (result
);
3226 m_locals
.safe_push (result
);
3230 /* Create a recording::block instance and add it to
3231 the functions's context's list of mementos, and to the function's
3234 Implements the post-error-checking part of
3235 gcc_jit_function_new_block. */
3238 recording::function::new_block (const char *name
)
3240 gcc_assert (m_kind
!= GCC_JIT_FUNCTION_IMPORTED
);
3242 recording::block
*result
=
3243 new recording::block (this, m_blocks
.length (), new_string (name
));
3244 m_ctxt
->record (result
);
3245 m_blocks
.safe_push (result
);
3249 /* Override the default implementation of
3250 recording::memento::write_to_dump by dumping a C-like
3251 representation of the function; either like a prototype
3252 for GCC_JIT_FUNCTION_IMPORTED, or like a full definition for
3253 all other kinds of function. */
3256 recording::function::write_to_dump (dump
&d
)
3260 default: gcc_unreachable ();
3261 case GCC_JIT_FUNCTION_EXPORTED
:
3262 case GCC_JIT_FUNCTION_IMPORTED
:
3263 d
.write ("extern ");
3265 case GCC_JIT_FUNCTION_INTERNAL
:
3266 d
.write ("static ");
3268 case GCC_JIT_FUNCTION_ALWAYS_INLINE
:
3269 d
.write ("static inline ");
3272 d
.write ("%s\n", m_return_type
->get_debug_string ());
3274 if (d
.update_locations ())
3275 m_loc
= d
.make_location ();
3277 d
.write ("%s (", get_debug_string ());
3280 recording::param
*param
;
3281 FOR_EACH_VEC_ELT (m_params
, i
, param
)
3286 param
->get_type ()->get_debug_string (),
3287 param
->get_debug_string ());
3290 if (m_kind
== GCC_JIT_FUNCTION_IMPORTED
)
3292 d
.write ("; /* (imported) */\n\n");
3302 FOR_EACH_VEC_ELT (m_locals
, i
, var
)
3303 var
->write_to_dump (d
);
3304 if (m_locals
.length ())
3307 /* Write each block: */
3308 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
3312 b
->write_to_dump (d
);
3319 /* Pre-compilation validation of a function, for those things we can't
3320 check until the context is (supposedly) fully-populated. */
3323 recording::function::validate ()
3325 /* Complain about empty functions with non-void return type. */
3326 if (m_kind
!= GCC_JIT_FUNCTION_IMPORTED
3327 && m_return_type
!= m_ctxt
->get_type (GCC_JIT_TYPE_VOID
))
3328 if (0 == m_blocks
.length ())
3329 m_ctxt
->add_error (m_loc
,
3330 "function %s returns non-void (type: %s)"
3331 " but has no blocks",
3332 get_debug_string (),
3333 m_return_type
->get_debug_string ());
3335 /* Check that all blocks are terminated. */
3336 int num_invalid_blocks
= 0;
3341 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
3342 if (!b
->validate ())
3343 num_invalid_blocks
++;
3346 /* Check that all blocks are reachable. */
3347 if (m_blocks
.length () > 0 && 0 == num_invalid_blocks
)
3349 /* Iteratively walk the graph of blocks, marking their "m_is_reachable"
3350 flag, starting at the initial block. */
3351 auto_vec
<block
*> worklist (m_blocks
.length ());
3352 worklist
.safe_push (m_blocks
[0]);
3353 while (worklist
.length () > 0)
3355 block
*b
= worklist
.pop ();
3356 b
->m_is_reachable
= true;
3358 /* Add successor blocks that aren't yet marked to the worklist. */
3359 /* We checked that each block has a terminating statement above . */
3360 block
*next1
, *next2
;
3361 int n
= b
->get_successor_blocks (&next1
, &next2
);
3367 if (!next2
->m_is_reachable
)
3368 worklist
.safe_push (next2
);
3371 if (!next1
->m_is_reachable
)
3372 worklist
.safe_push (next1
);
3379 /* Now complain about any blocks that haven't been marked. */
3383 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
3384 if (!b
->m_is_reachable
)
3385 m_ctxt
->add_error (b
->get_loc (),
3386 "unreachable block: %s",
3387 b
->get_debug_string ());
3392 /* Implements the post-error-checking part of
3393 gcc_jit_function_dump_to_dot. */
3396 recording::function::dump_to_dot (const char *path
)
3398 FILE *fp
= fopen (path
, "w");
3402 pretty_printer the_pp
;
3403 the_pp
.buffer
->stream
= fp
;
3405 pretty_printer
*pp
= &the_pp
;
3408 "digraph %s {\n", get_debug_string ());
3414 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
3415 b
->dump_to_dot (pp
);
3422 FOR_EACH_VEC_ELT (m_blocks
, i
, b
)
3423 b
->dump_edges_to_dot (pp
);
3426 pp_printf (pp
, "}\n");
3431 /* Implementation of recording::memento::make_debug_string for
3435 recording::function::make_debug_string ()
3440 /* A table of enum gcc_jit_function_kind values expressed in string
3443 static const char * const names_of_function_kinds
[] = {
3444 "GCC_JIT_FUNCTION_EXPORTED",
3445 "GCC_JIT_FUNCTION_INTERNAL",
3446 "GCC_JIT_FUNCTION_IMPORTED",
3447 "GCC_JIT_FUNCTION_ALWAYS_INLINE"
3450 /* Implementation of recording::memento::write_reproducer for functions. */
3453 recording::function::write_reproducer (reproducer
&r
)
3455 const char *id
= r
.make_identifier (this, "func");
3459 r
.write (" gcc_jit_function *%s =\n"
3460 " gcc_jit_context_get_builtin_function (%s,\n"
3463 r
.get_identifier (get_context ()),
3464 m_name
->get_debug_string ());
3467 const char *params_id
= r
.make_tmp_identifier ("params_for", this);
3468 r
.write (" gcc_jit_param *%s[%i] = {\n",
3470 m_params
.length ());
3473 FOR_EACH_VEC_ELT (m_params
, i
, param
)
3474 r
.write (" %s,\n", r
.get_identifier (param
));
3476 r
.write (" gcc_jit_function *%s =\n"
3477 " gcc_jit_context_new_function (%s, /* gcc_jit_context *ctxt */\n"
3478 " %s, /* gcc_jit_location *loc */\n"
3479 " %s, /* enum gcc_jit_function_kind kind */\n"
3480 " %s, /* gcc_jit_type *return_type */\n"
3481 " %s, /* const char *name */\n"
3482 " %i, /* int num_params */\n"
3483 " %s, /* gcc_jit_param **params */\n"
3484 " %i); /* int is_variadic */\n",
3486 r
.get_identifier (get_context ()),
3487 r
.get_identifier (m_loc
),
3488 names_of_function_kinds
[m_kind
],
3489 r
.get_identifier_as_type (m_return_type
),
3490 m_name
->get_debug_string (),
3497 /* The implementation of class gcc::jit::recording::block. */
3499 /* Create a recording::eval instance and add it to
3500 the block's context's list of mementos, and to the block's
3503 Implements the heart of gcc_jit_block_add_eval. */
3505 recording::statement
*
3506 recording::block::add_eval (recording::location
*loc
,
3507 recording::rvalue
*rvalue
)
3509 statement
*result
= new eval (this, loc
, rvalue
);
3510 m_ctxt
->record (result
);
3511 m_statements
.safe_push (result
);
3515 /* Create a recording::assignment instance and add it to
3516 the block's context's list of mementos, and to the block's
3519 Implements the heart of gcc_jit_block_add_assignment. */
3521 recording::statement
*
3522 recording::block::add_assignment (recording::location
*loc
,
3523 recording::lvalue
*lvalue
,
3524 recording::rvalue
*rvalue
)
3526 statement
*result
= new assignment (this, loc
, lvalue
, rvalue
);
3527 m_ctxt
->record (result
);
3528 m_statements
.safe_push (result
);
3532 /* Create a recording::assignment_op instance and add it to
3533 the block's context's list of mementos, and to the block's
3536 Implements the heart of gcc_jit_block_add_assignment_op. */
3538 recording::statement
*
3539 recording::block::add_assignment_op (recording::location
*loc
,
3540 recording::lvalue
*lvalue
,
3541 enum gcc_jit_binary_op op
,
3542 recording::rvalue
*rvalue
)
3544 statement
*result
= new assignment_op (this, loc
, lvalue
, op
, rvalue
);
3545 m_ctxt
->record (result
);
3546 m_statements
.safe_push (result
);
3550 /* Create a recording::comment instance and add it to
3551 the block's context's list of mementos, and to the block's
3554 Implements the heart of gcc_jit_block_add_comment. */
3556 recording::statement
*
3557 recording::block::add_comment (recording::location
*loc
,
3560 statement
*result
= new comment (this, loc
, new_string (text
));
3561 m_ctxt
->record (result
);
3562 m_statements
.safe_push (result
);
3566 /* Create a recording::end_with_conditional instance and add it to
3567 the block's context's list of mementos, and to the block's
3570 Implements the heart of gcc_jit_block_end_with_conditional. */
3572 recording::statement
*
3573 recording::block::end_with_conditional (recording::location
*loc
,
3574 recording::rvalue
*boolval
,
3575 recording::block
*on_true
,
3576 recording::block
*on_false
)
3578 statement
*result
= new conditional (this, loc
, boolval
, on_true
, on_false
);
3579 m_ctxt
->record (result
);
3580 m_statements
.safe_push (result
);
3581 m_has_been_terminated
= true;
3585 /* Create a recording::end_with_jump instance and add it to
3586 the block's context's list of mementos, and to the block's
3589 Implements the heart of gcc_jit_block_end_with_jump. */
3591 recording::statement
*
3592 recording::block::end_with_jump (recording::location
*loc
,
3593 recording::block
*target
)
3595 statement
*result
= new jump (this, loc
, target
);
3596 m_ctxt
->record (result
);
3597 m_statements
.safe_push (result
);
3598 m_has_been_terminated
= true;
3602 /* Create a recording::end_with_return instance and add it to
3603 the block's context's list of mementos, and to the block's
3606 Implements the post-error-checking parts of
3607 gcc_jit_block_end_with_return and
3608 gcc_jit_block_end_with_void_return. */
3610 recording::statement
*
3611 recording::block::end_with_return (recording::location
*loc
,
3612 recording::rvalue
*rvalue
)
3614 /* This is used by both gcc_jit_function_add_return and
3615 gcc_jit_function_add_void_return; rvalue will be non-NULL for
3616 the former and NULL for the latter. */
3617 statement
*result
= new return_ (this, loc
, rvalue
);
3618 m_ctxt
->record (result
);
3619 m_statements
.safe_push (result
);
3620 m_has_been_terminated
= true;
3624 /* Override the default implementation of
3625 recording::memento::write_to_dump for blocks by writing
3626 an unindented block name as a label, followed by the indented
3636 recording::block::write_to_dump (dump
&d
)
3638 d
.write ("%s:\n", get_debug_string ());
3642 FOR_EACH_VEC_ELT (m_statements
, i
, s
)
3643 s
->write_to_dump (d
);
3646 /* Validate a block by ensuring that it has been terminated. */
3649 recording::block::validate ()
3651 /* Check for termination. */
3652 if (!has_been_terminated ())
3654 statement
*stmt
= get_last_statement ();
3655 location
*loc
= stmt
? stmt
->get_loc () : NULL
;
3656 m_func
->get_context ()->add_error (loc
,
3657 "unterminated block in %s: %s",
3658 m_func
->get_debug_string (),
3659 get_debug_string ());
3666 /* Get the source-location of a block by using that of the first
3667 statement within it, if any. */
3669 recording::location
*
3670 recording::block::get_loc () const
3672 recording::statement
*stmt
= get_first_statement ();
3674 return stmt
->get_loc ();
3679 /* Get the first statement within a block, if any. */
3681 recording::statement
*
3682 recording::block::get_first_statement () const
3684 if (m_statements
.length ())
3685 return m_statements
[0];
3690 /* Get the last statement within a block, if any. */
3692 recording::statement
*
3693 recording::block::get_last_statement () const
3695 if (m_statements
.length ())
3696 return m_statements
[m_statements
.length () - 1];
3701 /* Assuming that this block has been terminated, get the number of
3702 successor blocks, which will be 0, 1 or 2, for return, unconditional
3703 jump, and conditional jump respectively.
3704 NEXT1 and NEXT2 must be non-NULL. The first successor block (if any)
3705 is written to NEXT1, and the second (if any) to NEXT2.
3707 Used when validating functions, and when dumping dot representations
3711 recording::block::get_successor_blocks (block
**next1
, block
**next2
) const
3713 gcc_assert (m_has_been_terminated
);
3716 statement
*last_statement
= get_last_statement ();
3717 gcc_assert (last_statement
);
3718 return last_statement
->get_successor_blocks (next1
, next2
);
3721 /* Implementation of pure virtual hook recording::memento::replay_into
3722 for recording::block. */
3725 recording::block::replay_into (replayer
*)
3727 set_playback_obj (m_func
->playback_function ()
3728 ->new_block (playback_string (m_name
)));
3731 /* Implementation of recording::memento::make_debug_string for
3735 recording::block::make_debug_string ()
3740 return string::from_printf (m_ctxt
,
3741 "<UNNAMED BLOCK %p>",
3745 /* Implementation of recording::memento::write_reproducer for blocks. */
3748 recording::block::write_reproducer (reproducer
&r
)
3750 const char *id
= r
.make_identifier (this, "block");
3751 r
.write (" gcc_jit_block *%s =\n"
3752 " gcc_jit_function_new_block (%s, %s);\n",
3754 r
.get_identifier (m_func
),
3755 m_name
? m_name
->get_debug_string () : "NULL");
3758 /* Dump a block in graphviz form into PP, capturing the block name (if
3759 any) and the statements. */
3762 recording::block::dump_to_dot (pretty_printer
*pp
)
3766 "[shape=record,style=filled,fillcolor=white,label=\"{"),
3768 pp_write_text_to_stream (pp
);
3771 pp_string (pp
, m_name
->c_str ());
3772 pp_string (pp
, ":");
3774 pp_write_text_as_dot_label_to_stream (pp
, true /*for_record*/);
3779 FOR_EACH_VEC_ELT (m_statements
, i
, s
)
3781 pp_string (pp
, s
->get_debug_string ());
3783 pp_write_text_as_dot_label_to_stream (pp
, true /*for_record*/);
3791 /* Dump the out-edges of the block in graphviz form into PP. */
3794 recording::block::dump_edges_to_dot (pretty_printer
*pp
)
3797 int num_succs
= get_successor_blocks (&next
[0], &next
[1]);
3798 for (int i
= 0; i
< num_succs
; i
++)
3800 "\tblock_%d:s -> block_%d:n;\n",
3801 m_index
, next
[i
]->m_index
);
3804 /* The implementation of class gcc::jit::recording::global. */
3806 /* Implementation of pure virtual hook recording::memento::replay_into
3807 for recording::global. */
3810 recording::global::replay_into (replayer
*r
)
3812 set_playback_obj (r
->new_global (playback_location (r
, m_loc
),
3814 m_type
->playback_type (),
3815 playback_string (m_name
)));
3818 /* Override the default implementation of
3819 recording::memento::write_to_dump for globals.
3820 This will be of the form:
3822 GCC_JIT_GLOBAL_EXPORTED:
3826 GCC_JIT_GLOBAL_INTERNAL:
3828 e.g. "static int foo;"
3830 GCC_JIT_GLOBAL_IMPORTED:
3832 e.g. "extern int foo;"
3834 These are written to the top of the dump by
3835 recording::context::dump_to_file. */
3838 recording::global::write_to_dump (dump
&d
)
3840 if (d
.update_locations ())
3841 m_loc
= d
.make_location ();
3848 case GCC_JIT_GLOBAL_EXPORTED
:
3851 case GCC_JIT_GLOBAL_INTERNAL
:
3852 d
.write ("static ");
3855 case GCC_JIT_GLOBAL_IMPORTED
:
3856 d
.write ("extern ");
3859 d
.write ("%s %s;\n",
3860 m_type
->get_debug_string (),
3861 get_debug_string ());
3864 /* A table of enum gcc_jit_global_kind values expressed in string
3867 static const char * const global_kind_reproducer_strings
[] = {
3868 "GCC_JIT_GLOBAL_EXPORTED",
3869 "GCC_JIT_GLOBAL_INTERNAL",
3870 "GCC_JIT_GLOBAL_IMPORTED"
3873 /* Implementation of recording::memento::write_reproducer for globals. */
3876 recording::global::write_reproducer (reproducer
&r
)
3878 const char *id
= r
.make_identifier (this, "block");
3879 r
.write (" gcc_jit_lvalue *%s =\n"
3880 " gcc_jit_context_new_global (%s, /* gcc_jit_context *ctxt */\n"
3881 " %s, /* gcc_jit_location *loc */\n"
3882 " %s, /* enum gcc_jit_global_kind kind */\n"
3883 " %s, /* gcc_jit_type *type */\n"
3884 " %s); /* const char *name */\n",
3886 r
.get_identifier (get_context ()),
3887 r
.get_identifier (m_loc
),
3888 global_kind_reproducer_strings
[m_kind
],
3889 r
.get_identifier_as_type (get_type ()),
3890 m_name
->get_debug_string ());
3893 /* The implementation of the various const-handling classes:
3894 gcc::jit::recording::memento_of_new_rvalue_from_const <HOST_TYPE>. */
3896 /* Explicit specialization of the various mementos we're interested in. */
3897 template class recording::memento_of_new_rvalue_from_const
<int>;
3898 template class recording::memento_of_new_rvalue_from_const
<long>;
3899 template class recording::memento_of_new_rvalue_from_const
<double>;
3900 template class recording::memento_of_new_rvalue_from_const
<void *>;
3902 /* Implementation of the pure virtual hook recording::memento::replay_into
3903 for recording::memento_of_new_rvalue_from_const <HOST_TYPE>. */
3905 template <typename HOST_TYPE
>
3908 memento_of_new_rvalue_from_const
<HOST_TYPE
>::replay_into (replayer
*r
)
3911 (r
->new_rvalue_from_const
<HOST_TYPE
> (m_type
->playback_type (),
3915 /* The make_debug_string and write_reproducer methods vary between the
3917 memento_of_new_rvalue_from_const <HOST_TYPE>
3918 classes, so we explicitly write specializations of them.
3920 I (dmalcolm) find the code to be clearer if the "recording" vs "playback"
3921 namespaces are written out explicitly, which is why most of this file
3922 doesn't abbreviate things by entering the "recording" namespace.
3924 However, these specializations are required to be in the same namespace
3925 as the template, hence we now have to enter the gcc::jit::recording
3931 /* The make_debug_string specialization for <int>, which renders it as
3932 (TARGET_TYPE)LITERAL
3938 memento_of_new_rvalue_from_const
<int>::make_debug_string ()
3940 return string::from_printf (m_ctxt
,
3942 m_type
->get_debug_string (),
3946 /* The write_reproducer specialization for <int>. */
3950 memento_of_new_rvalue_from_const
<int>::write_reproducer (reproducer
&r
)
3952 const char *id
= r
.make_identifier (this, "rvalue");
3953 r
.write (" gcc_jit_rvalue *%s =\n"
3954 " gcc_jit_context_new_rvalue_from_int (%s, /* gcc_jit_context *ctxt */\n"
3955 " %s, /* gcc_jit_type *numeric_type */\n"
3956 " %i); /* int value */\n",
3958 r
.get_identifier (get_context ()),
3959 r
.get_identifier_as_type (m_type
),
3963 /* The make_debug_string specialization for <long>, rendering it as
3964 (TARGET_TYPE)LITERAL
3970 memento_of_new_rvalue_from_const
<long>::make_debug_string ()
3972 return string::from_printf (m_ctxt
,
3974 m_type
->get_debug_string (),
3978 /* The write_reproducer specialization for <long>. */
3982 recording::memento_of_new_rvalue_from_const
<long>::write_reproducer (reproducer
&r
)
3984 const char *id
= r
.make_identifier (this, "rvalue");
3986 /* We have to special-case LONG_MIN, since e.g.
3987 -9223372036854775808L
3989 -(9223372036854775808L)
3991 error: integer constant is so large that it is unsigned [-Werror]
3992 Workaround this by writing (LONG_MIN + 1) - 1. */
3993 if (m_value
== LONG_MIN
)
3995 r
.write (" gcc_jit_rvalue *%s =\n"
3996 " gcc_jit_context_new_rvalue_from_long (%s, /* gcc_jit_context *ctxt */\n"
3997 " %s, /* gcc_jit_type *numeric_type */\n"
3998 " %ldL - 1); /* long value */\n",
4000 r
.get_identifier (get_context ()),
4001 r
.get_identifier_as_type (m_type
),
4006 r
.write (" gcc_jit_rvalue *%s =\n"
4007 " gcc_jit_context_new_rvalue_from_long (%s, /* gcc_jit_context *ctxt */\n"
4008 " %s, /* gcc_jit_type *numeric_type */\n"
4009 " %ldL); /* long value */\n",
4011 r
.get_identifier (get_context ()),
4012 r
.get_identifier_as_type (m_type
),
4016 /* The make_debug_string specialization for <double>, rendering it as
4017 (TARGET_TYPE)LITERAL
4023 memento_of_new_rvalue_from_const
<double>::make_debug_string ()
4025 return string::from_printf (m_ctxt
,
4027 m_type
->get_debug_string (),
4031 /* The write_reproducer specialization for <double>. */
4035 recording::memento_of_new_rvalue_from_const
<double>::write_reproducer (reproducer
&r
)
4037 const char *id
= r
.make_identifier (this, "rvalue");
4038 r
.write (" gcc_jit_rvalue *%s =\n"
4039 " gcc_jit_context_new_rvalue_from_double (%s, /* gcc_jit_context *ctxt */\n"
4040 " %s, /* gcc_jit_type *numeric_type */\n"
4041 " %f); /* double value */\n",
4043 r
.get_identifier (get_context ()),
4044 r
.get_identifier_as_type (m_type
),
4048 /* The make_debug_string specialization for <void *>, rendering it as
4053 Zero is rendered as NULL e.g.
4058 memento_of_new_rvalue_from_const
<void *>::make_debug_string ()
4060 if (m_value
!= NULL
)
4061 return string::from_printf (m_ctxt
,
4063 m_type
->get_debug_string (), m_value
);
4065 return string::from_printf (m_ctxt
,
4067 m_type
->get_debug_string ());
4070 /* Implementation of recording::memento::write_reproducer for <void *>
4075 memento_of_new_rvalue_from_const
<void *>::write_reproducer (reproducer
&r
)
4077 const char *id
= r
.make_identifier (this, "rvalue");
4079 r
.write (" gcc_jit_rvalue *%s =\n"
4080 " gcc_jit_context_new_rvalue_from_ptr (%s, /* gcc_jit_context *ctxt */\n"
4081 " %s, /* gcc_jit_type *pointer_type */\n"
4082 " (void *)%p); /* void *value */\n",
4084 r
.get_identifier (get_context ()),
4085 r
.get_identifier_as_type (m_type
),
4088 r
.write (" gcc_jit_rvalue *%s =\n"
4089 " gcc_jit_context_null (%s, /* gcc_jit_context *ctxt */\n"
4090 " %s); /* gcc_jit_type *pointer_type */\n",
4092 r
.get_identifier (get_context ()),
4093 r
.get_identifier_as_type (m_type
));
4096 /* We're done specializing make_debug_string and write_reproducer, so we
4097 can exit the gcc::jit::recording namespace. */
4099 } // namespace recording
4101 /* The implementation of class gcc::jit::recording::memento_of_new_string_literal. */
4103 /* Implementation of pure virtual hook recording::memento::replay_into
4104 for recording::memento_of_new_string_literal. */
4107 recording::memento_of_new_string_literal::replay_into (replayer
*r
)
4109 set_playback_obj (r
->new_string_literal (m_value
->c_str ()));
4112 /* Implementation of recording::memento::make_debug_string for
4116 recording::memento_of_new_string_literal::make_debug_string ()
4118 return string::from_printf (m_ctxt
,
4120 m_value
->get_debug_string ());
4123 /* Implementation of recording::memento::write_reproducer for string literal
4127 recording::memento_of_new_string_literal::write_reproducer (reproducer
&r
)
4129 const char *id
= r
.make_identifier (this, "rvalue");
4130 r
.write (" gcc_jit_rvalue *%s =\n"
4131 " gcc_jit_context_new_string_literal (%s, /* gcc_jit_context *ctxt */\n"
4132 " %s); /* const char *value */\n",
4134 r
.get_identifier (get_context ()),
4135 m_value
->get_debug_string ());
4138 /* The implementation of class gcc::jit::recording::unary_op. */
4140 /* Implementation of pure virtual hook recording::memento::replay_into
4141 for recording::unary_op. */
4144 recording::unary_op::replay_into (replayer
*r
)
4146 set_playback_obj (r
->new_unary_op (playback_location (r
, m_loc
),
4148 get_type ()->playback_type (),
4149 m_a
->playback_rvalue ()));
4152 /* Implementation of pure virtual hook recording::rvalue::visit_children
4153 for recording::unary_op. */
4155 recording::unary_op::visit_children (rvalue_visitor
*v
)
4160 /* Implementation of recording::memento::make_debug_string for
4163 static const char * const unary_op_strings
[] = {
4164 "-", /* GCC_JIT_UNARY_OP_MINUS */
4165 "~", /* GCC_JIT_UNARY_OP_BITWISE_NEGATE */
4166 "!", /* GCC_JIT_UNARY_OP_LOGICAL_NEGATE */
4167 "abs ", /* GCC_JIT_UNARY_OP_ABS */
4171 recording::unary_op::make_debug_string ()
4173 return string::from_printf (m_ctxt
,
4175 unary_op_strings
[m_op
],
4176 m_a
->get_debug_string ());
4179 static const char * const unary_op_reproducer_strings
[] = {
4180 "GCC_JIT_UNARY_OP_MINUS",
4181 "GCC_JIT_UNARY_OP_BITWISE_NEGATE",
4182 "GCC_JIT_UNARY_OP_LOGICAL_NEGATE",
4183 "GCC_JIT_UNARY_OP_ABS"
4186 /* Implementation of recording::memento::write_reproducer for unary ops. */
4189 recording::unary_op::write_reproducer (reproducer
&r
)
4191 const char *id
= r
.make_identifier (this, "rvalue");
4192 r
.write (" gcc_jit_rvalue *%s =\n"
4193 " gcc_jit_context_new_unary_op (%s,\n"
4194 " %s, /* gcc_jit_location *loc */\n"
4195 " %s, /* enum gcc_jit_unary_op op */\n"
4196 " %s, /* gcc_jit_type *result_type */\n"
4197 " %s); /* gcc_jit_rvalue *a */\n",
4199 r
.get_identifier (get_context ()),
4200 r
.get_identifier (m_loc
),
4201 unary_op_reproducer_strings
[m_op
],
4202 r
.get_identifier_as_type (get_type ()),
4203 r
.get_identifier_as_rvalue (m_a
));
4206 /* The implementation of class gcc::jit::recording::binary_op. */
4208 /* Implementation of pure virtual hook recording::memento::replay_into
4209 for recording::binary_op. */
4212 recording::binary_op::replay_into (replayer
*r
)
4214 set_playback_obj (r
->new_binary_op (playback_location (r
, m_loc
),
4216 get_type ()->playback_type (),
4217 m_a
->playback_rvalue (),
4218 m_b
->playback_rvalue ()));
4221 /* Implementation of pure virtual hook recording::rvalue::visit_children
4222 for recording::binary_op. */
4224 recording::binary_op::visit_children (rvalue_visitor
*v
)
4230 /* Implementation of recording::memento::make_debug_string for
4233 static const char * const binary_op_strings
[] = {
4234 "+", /* GCC_JIT_BINARY_OP_PLUS */
4235 "-", /* GCC_JIT_BINARY_OP_MINUS */
4236 "*", /* GCC_JIT_BINARY_OP_MULT */
4237 "/", /* GCC_JIT_BINARY_OP_DIVIDE */
4238 "%", /* GCC_JIT_BINARY_OP_MODULO */
4239 "&", /* GCC_JIT_BINARY_OP_BITWISE_AND */
4240 "^", /* GCC_JIT_BINARY_OP_BITWISE_XOR */
4241 "|", /* GCC_JIT_BINARY_OP_BITWISE_OR */
4242 "&&", /* GCC_JIT_BINARY_OP_LOGICAL_AND */
4243 "||", /* GCC_JIT_BINARY_OP_LOGICAL_OR */
4244 "<<", /* GCC_JIT_BINARY_OP_LSHIFT */
4245 ">>", /* GCC_JIT_BINARY_OP_RSHIFT */
4249 recording::binary_op::make_debug_string ()
4251 return string::from_printf (m_ctxt
,
4253 m_a
->get_debug_string (),
4254 binary_op_strings
[m_op
],
4255 m_b
->get_debug_string ());
4258 static const char * const binary_op_reproducer_strings
[] = {
4259 "GCC_JIT_BINARY_OP_PLUS",
4260 "GCC_JIT_BINARY_OP_MINUS",
4261 "GCC_JIT_BINARY_OP_MULT",
4262 "GCC_JIT_BINARY_OP_DIVIDE",
4263 "GCC_JIT_BINARY_OP_MODULO",
4264 "GCC_JIT_BINARY_OP_BITWISE_AND",
4265 "GCC_JIT_BINARY_OP_BITWISE_XOR",
4266 "GCC_JIT_BINARY_OP_BITWISE_OR",
4267 "GCC_JIT_BINARY_OP_LOGICAL_AND",
4268 "GCC_JIT_BINARY_OP_LOGICAL_OR",
4269 "GCC_JIT_BINARY_OP_LSHIFT",
4270 "GCC_JIT_BINARY_OP_RSHIFT"
4273 /* Implementation of recording::memento::write_reproducer for binary ops. */
4276 recording::binary_op::write_reproducer (reproducer
&r
)
4278 const char *id
= r
.make_identifier (this, "rvalue");
4279 r
.write (" gcc_jit_rvalue *%s =\n"
4280 " gcc_jit_context_new_binary_op (%s,\n"
4281 " %s, /* gcc_jit_location *loc */\n"
4282 " %s, /* enum gcc_jit_binary_op op */\n"
4283 " %s, /* gcc_jit_type *result_type */\n"
4284 " %s, /* gcc_jit_rvalue *a */\n"
4285 " %s); /* gcc_jit_rvalue *b */\n",
4287 r
.get_identifier (get_context ()),
4288 r
.get_identifier (m_loc
),
4289 binary_op_reproducer_strings
[m_op
],
4290 r
.get_identifier_as_type (get_type ()),
4291 r
.get_identifier_as_rvalue (m_a
),
4292 r
.get_identifier_as_rvalue (m_b
));
4295 /* The implementation of class gcc::jit::recording::comparison. */
4297 /* Implementation of recording::memento::make_debug_string for
4300 static const char * const comparison_strings
[] =
4302 "==", /* GCC_JIT_COMPARISON_EQ */
4303 "!=", /* GCC_JIT_COMPARISON_NE */
4304 "<", /* GCC_JIT_COMPARISON_LT */
4305 "<=", /* GCC_JIT_COMPARISON_LE */
4306 ">", /* GCC_JIT_COMPARISON_GT */
4307 ">=", /* GCC_JIT_COMPARISON_GE */
4311 recording::comparison::make_debug_string ()
4313 return string::from_printf (m_ctxt
,
4315 m_a
->get_debug_string (),
4316 comparison_strings
[m_op
],
4317 m_b
->get_debug_string ());
4320 /* A table of enum gcc_jit_comparison values expressed in string
4323 static const char * const comparison_reproducer_strings
[] =
4325 "GCC_JIT_COMPARISON_EQ",
4326 "GCC_JIT_COMPARISON_NE",
4327 "GCC_JIT_COMPARISON_LT",
4328 "GCC_JIT_COMPARISON_LE",
4329 "GCC_JIT_COMPARISON_GT",
4330 "GCC_JIT_COMPARISON_GE"
4333 /* Implementation of recording::memento::write_reproducer for comparisons. */
4336 recording::comparison::write_reproducer (reproducer
&r
)
4338 const char *id
= r
.make_identifier (this, "rvalue");
4339 r
.write (" gcc_jit_rvalue *%s =\n"
4340 " gcc_jit_context_new_comparison (%s,\n"
4341 " %s, /* gcc_jit_location *loc */\n"
4342 " %s, /* enum gcc_jit_comparison op */\n"
4343 " %s, /* gcc_jit_rvalue *a */\n"
4344 " %s); /* gcc_jit_rvalue *b */\n",
4346 r
.get_identifier (get_context ()),
4347 r
.get_identifier (m_loc
),
4348 comparison_reproducer_strings
[m_op
],
4349 r
.get_identifier_as_rvalue (m_a
),
4350 r
.get_identifier_as_rvalue (m_b
));
4353 /* Implementation of pure virtual hook recording::memento::replay_into
4354 for recording::comparison. */
4357 recording::comparison::replay_into (replayer
*r
)
4359 set_playback_obj (r
->new_comparison (playback_location (r
, m_loc
),
4361 m_a
->playback_rvalue (),
4362 m_b
->playback_rvalue ()));
4365 /* Implementation of pure virtual hook recording::rvalue::visit_children
4366 for recording::comparison. */
4369 recording::comparison::visit_children (rvalue_visitor
*v
)
4375 /* Implementation of pure virtual hook recording::memento::replay_into
4376 for recording::cast. */
4379 recording::cast::replay_into (replayer
*r
)
4381 set_playback_obj (r
->new_cast (playback_location (r
, m_loc
),
4382 m_rvalue
->playback_rvalue (),
4383 get_type ()->playback_type ()));
4386 /* Implementation of pure virtual hook recording::rvalue::visit_children
4387 for recording::cast. */
4389 recording::cast::visit_children (rvalue_visitor
*v
)
4391 v
->visit (m_rvalue
);
4394 /* Implementation of recording::memento::make_debug_string for
4398 recording::cast::make_debug_string ()
4400 return string::from_printf (m_ctxt
,
4402 get_type ()->get_debug_string (),
4403 m_rvalue
->get_debug_string ());
4406 /* Implementation of recording::memento::write_reproducer for casts. */
4409 recording::cast::write_reproducer (reproducer
&r
)
4411 const char *id
= r
.make_identifier (this, "rvalue");
4412 r
.write (" gcc_jit_rvalue *%s =\n"
4413 " gcc_jit_context_new_cast (%s,\n"
4414 " %s, /* gcc_jit_location *loc */\n"
4415 " %s, /* gcc_jit_rvalue *rvalue */\n"
4416 " %s); /* gcc_jit_type *type */\n",
4418 r
.get_identifier (get_context ()),
4419 r
.get_identifier (m_loc
),
4420 r
.get_identifier_as_rvalue (m_rvalue
),
4421 r
.get_identifier_as_type (get_type ()));
4424 /* The implementation of class gcc::jit::recording::call. */
4426 /* The constructor for gcc::jit::recording::call. */
4428 recording::call::call (recording::context
*ctxt
,
4429 recording::location
*loc
,
4430 recording::function
*func
,
4433 : rvalue (ctxt
, loc
, func
->get_return_type ()),
4437 for (int i
= 0; i
< numargs
; i
++)
4438 m_args
.safe_push (args
[i
]);
4441 /* Implementation of pure virtual hook recording::memento::replay_into
4442 for recording::call. */
4445 recording::call::replay_into (replayer
*r
)
4447 auto_vec
<playback::rvalue
*> playback_args
;
4448 playback_args
.create (m_args
.length ());
4449 for (unsigned i
= 0; i
< m_args
.length (); i
++)
4450 playback_args
.safe_push (m_args
[i
]->playback_rvalue ());
4452 set_playback_obj (r
->new_call (playback_location (r
, m_loc
),
4453 m_func
->playback_function (),
4457 /* Implementation of pure virtual hook recording::rvalue::visit_children
4458 for recording::call. */
4461 recording::call::visit_children (rvalue_visitor
*v
)
4463 for (unsigned i
= 0; i
< m_args
.length (); i
++)
4464 v
->visit (m_args
[i
]);
4467 /* Implementation of recording::memento::make_debug_string for
4471 recording::call::make_debug_string ()
4473 /* First, build a buffer for the arguments. */
4474 /* Calculate length of said buffer. */
4475 size_t sz
= 1; /* nil terminator */
4476 for (unsigned i
= 0; i
< m_args
.length (); i
++)
4478 sz
+= strlen (m_args
[i
]->get_debug_string ());
4479 sz
+= 2; /* ", " separator */
4482 /* Now allocate and populate the buffer. */
4483 char *argbuf
= new char[sz
];
4486 for (unsigned i
= 0; i
< m_args
.length (); i
++)
4488 strcpy (argbuf
+ len
, m_args
[i
]->get_debug_string ());
4489 len
+= strlen (m_args
[i
]->get_debug_string ());
4490 if (i
+ 1 < m_args
.length ())
4492 strcpy (argbuf
+ len
, ", ");
4498 /* ...and use it to get the string for the call as a whole. */
4499 string
*result
= string::from_printf (m_ctxt
,
4501 m_func
->get_debug_string (),
4510 recording::call::write_reproducer (reproducer
&r
)
4512 const char *id
= r
.make_identifier (this, "call");
4513 const char *args_id
= r
.make_tmp_identifier ("args_for_", this);
4514 r
.write (" gcc_jit_rvalue *%s[%i] = {\n",
4517 for (unsigned i
= 0; i
< m_args
.length (); i
++)
4518 r
.write (" %s,\n", r
.get_identifier_as_rvalue (m_args
[i
]));
4520 r
.write (" gcc_jit_rvalue *%s =\n"
4521 " gcc_jit_context_new_call (%s, /* gcc_jit_context *ctxt */\n"
4522 " %s, /* gcc_jit_location *loc */\n"
4523 " %s, /* gcc_jit_function *func */\n"
4524 " %i, /* int numargs */ \n"
4525 " %s); /* gcc_jit_rvalue **args*/\n",
4527 r
.get_identifier (get_context ()),
4528 r
.get_identifier (m_loc
),
4529 r
.get_identifier (m_func
),
4534 /* The implementation of class gcc::jit::recording::call_through_ptr. */
4536 /* The constructor for recording::call_through_ptr. */
4538 recording::call_through_ptr::call_through_ptr (recording::context
*ctxt
,
4539 recording::location
*loc
,
4540 recording::rvalue
*fn_ptr
,
4543 : rvalue (ctxt
, loc
,
4544 fn_ptr
->get_type ()->dereference ()
4545 ->as_a_function_type ()->get_return_type ()),
4549 for (int i
= 0; i
< numargs
; i
++)
4550 m_args
.safe_push (args
[i
]);
4553 /* Implementation of pure virtual hook recording::memento::replay_into
4554 for recording::call_through_ptr. */
4557 recording::call_through_ptr::replay_into (replayer
*r
)
4559 auto_vec
<playback::rvalue
*> playback_args
;
4560 playback_args
.create (m_args
.length ());
4561 for (unsigned i
= 0; i
< m_args
.length (); i
++)
4562 playback_args
.safe_push (m_args
[i
]->playback_rvalue ());
4564 set_playback_obj (r
->new_call_through_ptr (playback_location (r
, m_loc
),
4565 m_fn_ptr
->playback_rvalue (),
4569 /* Implementation of pure virtual hook recording::rvalue::visit_children
4570 for recording::call_through_ptr. */
4573 recording::call_through_ptr::visit_children (rvalue_visitor
*v
)
4575 v
->visit (m_fn_ptr
);
4576 for (unsigned i
= 0; i
< m_args
.length (); i
++)
4577 v
->visit (m_args
[i
]);
4580 /* Implementation of recording::memento::make_debug_string for
4581 calls through function ptrs. */
4584 recording::call_through_ptr::make_debug_string ()
4586 /* First, build a buffer for the arguments. */
4587 /* Calculate length of said buffer. */
4588 size_t sz
= 1; /* nil terminator */
4589 for (unsigned i
= 0; i
< m_args
.length (); i
++)
4591 sz
+= strlen (m_args
[i
]->get_debug_string ());
4592 sz
+= 2; /* ", " separator */
4595 /* Now allocate and populate the buffer. */
4596 char *argbuf
= new char[sz
];
4599 for (unsigned i
= 0; i
< m_args
.length (); i
++)
4601 strcpy (argbuf
+ len
, m_args
[i
]->get_debug_string ());
4602 len
+= strlen (m_args
[i
]->get_debug_string ());
4603 if (i
+ 1 < m_args
.length ())
4605 strcpy (argbuf
+ len
, ", ");
4611 /* ...and use it to get the string for the call as a whole. */
4612 string
*result
= string::from_printf (m_ctxt
,
4614 m_fn_ptr
->get_debug_string (),
4622 /* Implementation of recording::memento::write_reproducer for
4623 call_through_ptr. */
4626 recording::call_through_ptr::write_reproducer (reproducer
&r
)
4628 const char *id
= r
.make_identifier (this, "call");
4629 const char *args_id
= r
.make_tmp_identifier ("args_for_", this);
4630 r
.write (" gcc_jit_rvalue *%s[%i] = {\n",
4633 for (unsigned i
= 0; i
< m_args
.length (); i
++)
4634 r
.write (" %s,\n", r
.get_identifier_as_rvalue (m_args
[i
]));
4636 r
.write (" gcc_jit_rvalue *%s =\n"
4637 " gcc_jit_context_new_call_through_ptr (%s, /* gcc_jit_context *ctxt */\n"
4638 " %s, /* gcc_jit_location *loc */\n"
4639 " %s, /* gcc_jit_rvalue *fn_ptr */\n"
4640 " %i, /* int numargs */ \n"
4641 " %s); /* gcc_jit_rvalue **args*/\n",
4643 r
.get_identifier (get_context ()),
4644 r
.get_identifier (m_loc
),
4645 r
.get_identifier_as_rvalue (m_fn_ptr
),
4650 /* The implementation of class gcc::jit::recording::array_access. */
4652 /* Implementation of pure virtual hook recording::memento::replay_into
4653 for recording::array_access. */
4656 recording::array_access::replay_into (replayer
*r
)
4659 r
->new_array_access (playback_location (r
, m_loc
),
4660 m_ptr
->playback_rvalue (),
4661 m_index
->playback_rvalue ()));
4664 /* Implementation of pure virtual hook recording::rvalue::visit_children
4665 for recording::array_access. */
4668 recording::array_access::visit_children (rvalue_visitor
*v
)
4674 /* Implementation of recording::memento::make_debug_string for
4678 recording::array_access::make_debug_string ()
4680 return string::from_printf (m_ctxt
,
4682 m_ptr
->get_debug_string (),
4683 m_index
->get_debug_string ());
4686 /* Implementation of recording::memento::write_reproducer for
4690 recording::array_access::write_reproducer (reproducer
&r
)
4692 const char *id
= r
.make_identifier (this, "lvalue");
4693 r
.write (" gcc_jit_lvalue *%s = \n"
4694 " gcc_jit_context_new_array_access (%s, /* gcc_jit_context *ctxt */\n"
4695 " %s, /*gcc_jit_location *loc */\n"
4696 " %s, /* gcc_jit_rvalue *ptr */\n"
4697 " %s); /* gcc_jit_rvalue *index */\n",
4699 r
.get_identifier (get_context ()),
4700 r
.get_identifier (m_loc
),
4701 r
.get_identifier_as_rvalue (m_ptr
),
4702 r
.get_identifier_as_rvalue (m_index
));
4705 /* The implementation of class gcc::jit::recording::access_field_of_lvalue. */
4707 /* Implementation of pure virtual hook recording::memento::replay_into
4708 for recording::access_field_of_lvalue. */
4711 recording::access_field_of_lvalue::replay_into (replayer
*r
)
4714 m_lvalue
->playback_lvalue ()
4715 ->access_field (playback_location (r
, m_loc
),
4716 m_field
->playback_field ()));
4720 /* Implementation of pure virtual hook recording::rvalue::visit_children
4721 for recording::access_field_of_lvalue. */
4724 recording::access_field_of_lvalue::visit_children (rvalue_visitor
*v
)
4726 v
->visit (m_lvalue
);
4729 /* Implementation of recording::memento::make_debug_string for
4730 accessing a field of an lvalue. */
4733 recording::access_field_of_lvalue::make_debug_string ()
4735 return string::from_printf (m_ctxt
,
4737 m_lvalue
->get_debug_string (),
4738 m_field
->get_debug_string ());
4741 /* Implementation of recording::memento::write_reproducer for
4742 access_field_of_lvalue. */
4745 recording::access_field_of_lvalue::write_reproducer (reproducer
&r
)
4747 const char *id
= r
.make_identifier (this, "lvalue");
4748 r
.write (" gcc_jit_lvalue *%s = \n"
4749 " gcc_jit_lvalue_access_field (%s, /*gcc_jit_lvalue *struct_or_union */\n"
4750 " %s, /*gcc_jit_location *loc */\n"
4753 r
.get_identifier_as_lvalue (m_lvalue
),
4754 r
.get_identifier (m_loc
),
4755 r
.get_identifier (m_field
));
4758 /* The implementation of class gcc::jit::recording::access_field_rvalue. */
4760 /* Implementation of pure virtual hook recording::memento::replay_into
4761 for recording::access_field_rvalue. */
4764 recording::access_field_rvalue::replay_into (replayer
*r
)
4767 m_rvalue
->playback_rvalue ()
4768 ->access_field (playback_location (r
, m_loc
),
4769 m_field
->playback_field ()));
4772 /* Implementation of pure virtual hook recording::rvalue::visit_children
4773 for recording::access_field_rvalue. */
4776 recording::access_field_rvalue::visit_children (rvalue_visitor
*v
)
4778 v
->visit (m_rvalue
);
4781 /* Implementation of recording::memento::make_debug_string for
4782 accessing a field of an rvalue. */
4785 recording::access_field_rvalue::make_debug_string ()
4787 return string::from_printf (m_ctxt
,
4789 m_rvalue
->get_debug_string (),
4790 m_field
->get_debug_string ());
4793 /* Implementation of recording::memento::write_reproducer for
4794 access_field_rvalue. */
4797 recording::access_field_rvalue::write_reproducer (reproducer
&r
)
4799 const char *id
= r
.make_identifier (this, "rvalue");
4800 r
.write (" gcc_jit_rvalue *%s = \n"
4801 " gcc_jit_rvalue_access_field (%s, /*gcc_jit_rvalue *struct_or_union */\n"
4802 " %s, /*gcc_jit_location *loc */\n"
4805 r
.get_identifier_as_rvalue (m_rvalue
),
4806 r
.get_identifier (m_loc
),
4807 r
.get_identifier (m_field
));
4810 /* The implementation of class
4811 gcc::jit::recording::dereference_field_rvalue. */
4813 /* Implementation of pure virtual hook recording::memento::replay_into
4814 for recording::dereference_field_rvalue. */
4817 recording::dereference_field_rvalue::replay_into (replayer
*r
)
4820 m_rvalue
->playback_rvalue ()->
4821 dereference_field (playback_location (r
, m_loc
),
4822 m_field
->playback_field ()));
4825 /* Implementation of pure virtual hook recording::rvalue::visit_children
4826 for recording::dereference_field_rvalue. */
4829 recording::dereference_field_rvalue::visit_children (rvalue_visitor
*v
)
4831 v
->visit (m_rvalue
);
4834 /* Implementation of recording::memento::make_debug_string for
4835 dereferencing a field of an rvalue. */
4838 recording::dereference_field_rvalue::make_debug_string ()
4840 return string::from_printf (m_ctxt
,
4842 m_rvalue
->get_debug_string (),
4843 m_field
->get_debug_string ());
4846 /* Implementation of recording::memento::write_reproducer for
4847 dereference_field_rvalue. */
4850 recording::dereference_field_rvalue::write_reproducer (reproducer
&r
)
4852 const char *id
= r
.make_identifier (this, "lvalue");
4853 r
.write (" gcc_jit_lvalue *%s=\n"
4854 " gcc_jit_rvalue_dereference_field (%s, /* gcc_jit_rvalue *ptr */\n"
4855 " %s, /* gcc_jit_location *loc */\n"
4856 " %s); /* gcc_jit_field *field */\n",
4858 r
.get_identifier_as_rvalue (m_rvalue
),
4859 r
.get_identifier (m_loc
),
4860 r
.get_identifier (m_field
));
4863 /* The implementation of class gcc::jit::recording::dereference_rvalue. */
4865 /* Implementation of pure virtual hook recording::memento::replay_into
4866 for recording::dereference_rvalue. */
4869 recording::dereference_rvalue::replay_into (replayer
*r
)
4872 m_rvalue
->playback_rvalue ()->
4873 dereference (playback_location (r
, m_loc
)));
4876 /* Implementation of pure virtual hook recording::rvalue::visit_children
4877 for recording::dereference_rvalue. */
4880 recording::dereference_rvalue::visit_children (rvalue_visitor
*v
)
4882 v
->visit (m_rvalue
);
4885 /* Implementation of recording::memento::make_debug_string for
4886 dereferencing an rvalue. */
4889 recording::dereference_rvalue::make_debug_string ()
4891 return string::from_printf (m_ctxt
,
4893 m_rvalue
->get_debug_string ());
4896 /* Implementation of recording::memento::write_reproducer for
4897 dereference_rvalue. */
4900 recording::dereference_rvalue::write_reproducer (reproducer
&r
)
4902 const char *id
= r
.make_identifier (this, "dereference");
4903 r
.write (" gcc_jit_lvalue *%s =\n"
4904 " gcc_jit_rvalue_dereference (%s, /* gcc_jit_rvalue *rvalue */\n"
4905 " %s); /* gcc_jit_location *loc */\n",
4907 r
.get_identifier_as_rvalue (m_rvalue
),
4908 r
.get_identifier (m_loc
));
4911 /* The implementation of class gcc::jit::recording::get_address_of_lvalue. */
4913 /* Implementation of pure virtual hook recording::memento::replay_into
4914 for recording::get_address_of_lvalue. */
4917 recording::get_address_of_lvalue::replay_into (replayer
*r
)
4920 m_lvalue
->playback_lvalue ()->
4921 get_address (playback_location (r
, m_loc
)));
4924 /* Implementation of pure virtual hook recording::rvalue::visit_children
4925 for recording::get_address_of_lvalue. */
4928 recording::get_address_of_lvalue::visit_children (rvalue_visitor
*v
)
4930 v
->visit (m_lvalue
);
4933 /* Implementation of recording::memento::make_debug_string for
4934 getting the address of an lvalue. */
4937 recording::get_address_of_lvalue::make_debug_string ()
4939 return string::from_printf (m_ctxt
,
4941 m_lvalue
->get_debug_string ());
4944 /* Implementation of recording::memento::write_reproducer for
4945 get_address_of_lvalue. */
4948 recording::get_address_of_lvalue::write_reproducer (reproducer
&r
)
4950 const char *id
= r
.make_identifier (this, "address_of");
4951 r
.write (" gcc_jit_rvalue *%s =\n"
4952 " gcc_jit_lvalue_get_address (%s, /* gcc_jit_lvalue *lvalue */\n"
4953 " %s); /* gcc_jit_location *loc */\n",
4955 r
.get_identifier_as_lvalue (m_lvalue
),
4956 r
.get_identifier (m_loc
));
4959 /* The implementation of class gcc::jit::recording::local. */
4961 /* Implementation of pure virtual hook recording::memento::replay_into
4962 for recording::local. */
4965 recording::local::replay_into (replayer
*r
)
4968 m_func
->playback_function ()
4969 ->new_local (playback_location (r
, m_loc
),
4970 m_type
->playback_type (),
4971 playback_string (m_name
)));
4974 /* Override the default implementation of
4975 recording::memento::write_to_dump for locals by writing
4977 for use at the top of the function body as if it were a
4981 recording::local::write_to_dump (dump
&d
)
4983 if (d
.update_locations ())
4984 m_loc
= d
.make_location ();
4985 d
.write(" %s %s;\n",
4986 m_type
->get_debug_string (),
4987 get_debug_string ());
4991 recording::local::write_reproducer (reproducer
&r
)
4993 const char *id
= r
.make_identifier (this, "local");
4994 r
.write (" gcc_jit_lvalue *%s =\n"
4995 " gcc_jit_function_new_local (%s, /* gcc_jit_function *func */\n"
4996 " %s, /* gcc_jit_location *loc */\n"
4997 " %s, /* gcc_jit_type *type */\n"
4998 " %s); /* const char *name */\n",
5000 r
.get_identifier (m_func
),
5001 r
.get_identifier (m_loc
),
5002 r
.get_identifier_as_type (m_type
),
5003 m_name
->get_debug_string ());
5006 /* The implementation of class gcc::jit::recording::statement. */
5008 /* We poison the default implementation of
5009 gcc::jit::recording::statement::get_successor_blocks
5010 since this vfunc must only ever be called on terminator
5014 recording::statement::get_successor_blocks (block
**/
*out_next1*/
,
5015 block
**/
*out_next2*/
) const
5017 /* The base class implementation is for non-terminating statements,
5018 and thus should never be called. */
5023 /* Extend the default implementation of
5024 recording::memento::write_to_dump for statements by (if requested)
5025 updating the location of the statement to the current location in
5029 recording::statement::write_to_dump (dump
&d
)
5031 memento::write_to_dump (d
);
5032 if (d
.update_locations ())
5033 m_loc
= d
.make_location ();
5036 /* The implementation of class gcc::jit::recording::eval. */
5038 /* Implementation of pure virtual hook recording::memento::replay_into
5039 for recording::eval. */
5042 recording::eval::replay_into (replayer
*r
)
5044 playback_block (get_block ())
5045 ->add_eval (playback_location (r
),
5046 m_rvalue
->playback_rvalue ());
5049 /* Implementation of recording::memento::make_debug_string for
5050 an eval statement. */
5053 recording::eval::make_debug_string ()
5055 return string::from_printf (m_ctxt
,
5057 m_rvalue
->get_debug_string ());
5060 /* Implementation of recording::memento::write_reproducer for
5064 recording::eval::write_reproducer (reproducer
&r
)
5066 r
.write (" gcc_jit_block_add_eval (%s, /*gcc_jit_block *block */\n"
5067 " %s, /* gcc_jit_location *loc */\n"
5068 " %s); /* gcc_jit_rvalue *rvalue */\n",
5069 r
.get_identifier (get_block ()),
5070 r
.get_identifier (get_loc ()),
5071 r
.get_identifier_as_rvalue (m_rvalue
));
5074 /* The implementation of class gcc::jit::recording::assignment. */
5076 /* Implementation of pure virtual hook recording::memento::replay_into
5077 for recording::assignment. */
5080 recording::assignment::replay_into (replayer
*r
)
5082 playback_block (get_block ())
5083 ->add_assignment (playback_location (r
),
5084 m_lvalue
->playback_lvalue (),
5085 m_rvalue
->playback_rvalue ());
5088 /* Implementation of recording::memento::make_debug_string for
5089 an assignment statement. */
5092 recording::assignment::make_debug_string ()
5094 return string::from_printf (m_ctxt
,
5096 m_lvalue
->get_debug_string (),
5097 m_rvalue
->get_debug_string ());
5100 /* Implementation of recording::memento::write_reproducer for
5101 assignment statements. */
5104 recording::assignment::write_reproducer (reproducer
&r
)
5106 r
.write (" gcc_jit_block_add_assignment (%s, /*gcc_jit_block *block */\n"
5107 " %s, /* gcc_jit_location *loc */\n"
5108 " %s, /* gcc_jit_lvalue *lvalue */\n"
5109 " %s); /* gcc_jit_rvalue *rvalue */\n",
5110 r
.get_identifier (get_block ()),
5111 r
.get_identifier (get_loc ()),
5112 r
.get_identifier_as_lvalue (m_lvalue
),
5113 r
.get_identifier_as_rvalue (m_rvalue
));
5116 /* The implementation of class gcc::jit::recording::assignment_op. */
5118 /* Implementation of pure virtual hook recording::memento::replay_into
5119 for recording::assignment_op. */
5122 recording::assignment_op::replay_into (replayer
*r
)
5124 playback::type
*result_type
=
5125 m_lvalue
->playback_lvalue ()->get_type ();
5127 playback::rvalue
*binary_op
=
5128 r
->new_binary_op (playback_location (r
),
5131 m_lvalue
->playback_rvalue (),
5132 m_rvalue
->playback_rvalue ());
5134 playback_block (get_block ())
5135 ->add_assignment (playback_location (r
),
5136 m_lvalue
->playback_lvalue (),
5140 /* Implementation of recording::memento::make_debug_string for
5141 an assignment_op statement. */
5144 recording::assignment_op::make_debug_string ()
5146 return string::from_printf (m_ctxt
,
5148 m_lvalue
->get_debug_string (),
5149 binary_op_strings
[m_op
],
5150 m_rvalue
->get_debug_string ());
5153 /* Implementation of recording::memento::write_reproducer for
5154 assignment_op statements. */
5157 recording::assignment_op::write_reproducer (reproducer
&r
)
5159 r
.write (" gcc_jit_block_add_assignment_op (%s, /*gcc_jit_block *block */\n"
5160 " %s, /* gcc_jit_location *loc */\n"
5161 " %s, /* gcc_jit_lvalue *lvalue */\n"
5162 " %s, /* enum gcc_jit_binary_op op */\n"
5163 " %s); /* gcc_jit_rvalue *rvalue */\n",
5164 r
.get_identifier (get_block ()),
5165 r
.get_identifier (get_loc ()),
5166 r
.get_identifier_as_lvalue (m_lvalue
),
5167 binary_op_reproducer_strings
[m_op
],
5168 r
.get_identifier_as_rvalue (m_rvalue
));
5171 /* The implementation of class gcc::jit::recording::comment. */
5173 /* Implementation of pure virtual hook recording::memento::replay_into
5174 for recording::comment. */
5177 recording::comment::replay_into (replayer
*r
)
5179 playback_block (get_block ())
5180 ->add_comment (playback_location (r
),
5184 /* Implementation of recording::memento::make_debug_string for
5185 a comment "statement". */
5188 recording::comment::make_debug_string ()
5190 return string::from_printf (m_ctxt
,
5195 /* Implementation of recording::memento::write_reproducer for
5199 recording::comment::write_reproducer (reproducer
&r
)
5201 r
.write (" gcc_jit_block_add_comment (%s, /*gcc_jit_block *block */\n"
5202 " %s, /* gcc_jit_location *loc */\n"
5203 " %s); /* const char *text */\n",
5204 r
.get_identifier (get_block ()),
5205 r
.get_identifier (get_loc ()),
5206 m_text
->get_debug_string ());
5209 /* The implementation of class gcc::jit::recording::conditional. */
5211 /* Implementation of pure virtual hook recording::memento::replay_into
5212 for recording::conditional. */
5215 recording::conditional::replay_into (replayer
*r
)
5217 playback_block (get_block ())
5218 ->add_conditional (playback_location (r
),
5219 m_boolval
->playback_rvalue (),
5220 playback_block (m_on_true
),
5221 playback_block (m_on_false
));
5224 /* Override the poisoned default implementation of
5225 gcc::jit::recording::statement::get_successor_blocks
5227 A conditional jump has 2 successor blocks. */
5230 recording::conditional::get_successor_blocks (block
**out_next1
,
5231 block
**out_next2
) const
5233 *out_next1
= m_on_true
;
5234 *out_next2
= m_on_false
;
5238 /* Implementation of recording::memento::make_debug_string for
5239 a conditional jump statement. */
5242 recording::conditional::make_debug_string ()
5245 return string::from_printf (m_ctxt
,
5246 "if (%s) goto %s; else goto %s;",
5247 m_boolval
->get_debug_string (),
5248 m_on_true
->get_debug_string (),
5249 m_on_false
->get_debug_string ());
5251 return string::from_printf (m_ctxt
,
5253 m_boolval
->get_debug_string (),
5254 m_on_true
->get_debug_string ());
5257 /* Implementation of recording::memento::write_reproducer for
5258 conditional statements. */
5261 recording::conditional::write_reproducer (reproducer
&r
)
5263 r
.write (" gcc_jit_block_end_with_conditional (%s, /*gcc_jit_block *block */\n"
5264 " %s, /* gcc_jit_location *loc */\n"
5265 " %s, /* gcc_jit_rvalue *boolval */\n"
5266 " %s, /* gcc_jit_block *on_true */\n"
5267 " %s); /* gcc_jit_block *on_false */\n",
5268 r
.get_identifier (get_block ()),
5269 r
.get_identifier (get_loc ()),
5270 r
.get_identifier_as_rvalue (m_boolval
),
5271 r
.get_identifier (m_on_true
),
5272 r
.get_identifier (m_on_false
));
5275 /* The implementation of class gcc::jit::recording::jump. */
5277 /* Implementation of pure virtual hook recording::memento::replay_into
5278 for recording::jump. */
5281 recording::jump::replay_into (replayer
*r
)
5283 playback_block (get_block ())
5284 ->add_jump (playback_location (r
),
5285 m_target
->playback_block ());
5288 /* Override the poisoned default implementation of
5289 gcc::jit::recording::statement::get_successor_blocks
5291 An unconditional jump has 1 successor block. */
5294 recording::jump::get_successor_blocks (block
**out_next1
,
5295 block
**/
*out_next2*/
) const
5297 *out_next1
= m_target
;
5301 /* Implementation of recording::memento::make_debug_string for
5302 a unconditional jump statement. */
5305 recording::jump::make_debug_string ()
5307 return string::from_printf (m_ctxt
,
5309 m_target
->get_debug_string ());
5312 /* Implementation of recording::memento::write_reproducer for
5316 recording::jump::write_reproducer (reproducer
&r
)
5318 r
.write (" gcc_jit_block_end_with_jump (%s, /*gcc_jit_block *block */\n"
5319 " %s, /* gcc_jit_location *loc */\n"
5320 " %s); /* gcc_jit_block *target */\n",
5321 r
.get_identifier (get_block ()),
5322 r
.get_identifier (get_loc ()),
5323 r
.get_identifier (m_target
));
5326 /* The implementation of class gcc::jit::recording::return_. */
5328 /* Implementation of pure virtual hook recording::memento::replay_into
5329 for recording::return_. */
5332 recording::return_::replay_into (replayer
*r
)
5334 playback_block (get_block ())
5335 ->add_return (playback_location (r
),
5336 m_rvalue
? m_rvalue
->playback_rvalue () : NULL
);
5339 /* Override the poisoned default implementation of
5340 gcc::jit::recording::statement::get_successor_blocks
5342 A return statement has no successor block. */
5345 recording::return_::get_successor_blocks (block
**/
*out_next1*/
,
5346 block
**/
*out_next2*/
) const
5351 /* Implementation of recording::memento::make_debug_string for
5352 a return statement (covers both those with and without rvalues). */
5355 recording::return_::make_debug_string ()
5358 return string::from_printf (m_ctxt
,
5360 m_rvalue
->get_debug_string ());
5362 return string::from_printf (m_ctxt
,
5366 /* Implementation of recording::memento::write_reproducer for
5367 return statements. */
5370 recording::return_::write_reproducer (reproducer
&r
)
5373 r
.write (" gcc_jit_block_end_with_return (%s, /*gcc_jit_block *block */\n"
5374 " %s, /* gcc_jit_location *loc */\n"
5375 " %s); /* gcc_jit_rvalue *rvalue */\n",
5376 r
.get_identifier (get_block ()),
5377 r
.get_identifier (get_loc ()),
5378 r
.get_identifier_as_rvalue (m_rvalue
));
5380 r
.write (" gcc_jit_block_end_with_void_return (%s, /*gcc_jit_block *block */\n"
5381 " %s); /* gcc_jit_location *loc */\n",
5382 r
.get_identifier (get_block ()),
5383 r
.get_identifier (get_loc ()));
5386 } // namespace gcc::jit